zoukankan      html  css  js  c++  java
  • Linux C double linked for any data type

    /**************************************************************************
     *            Linux C double linked for any data type
     * 声明:
     *      提供一种双链接口,可以保存保存任何类型的数据。
     *                  
     *                                  2015-12-25 晴 深圳 南山平山村 曾剑锋
     *************************************************************************/
    
                        \\\\-*- 目录 -*-////////
                        |  一、cat double_linked.h
                        |  二、cat myerror.h
                        |  三、cat doulbe_linked.c
                        |  四、cat main.c
                        ---------------------------
    
    一、cat double_linked.h
        #ifndef __DOUBLE_LINK_H__
            #define __DOUBLE_LINK_H__
            
            #include <stdio.h>
            #include <stdlib.h>
            #include "myerror.h"
            #include <string.h>
    
            typedef struct DOUBLE_LINKED{
                void* datap;
                int size;
                struct DOUBLE_LINKED* pre;
                struct DOUBLE_LINKED* next;
            } double_linked;
    
            typedef void(*double_linked_print)(double_linked* data);
            typedef int(*double_linked_delete)(void* data, double_linked* linked_data);
    
            void init_double_linked_node(double_linked* node);
            int check_data_size(void* data, int size);
            void empty_double_linked(double_linked* header);
            void _delete_double_linked_node(double_linked* pre, double_linked* next);
            void delete_double_linked_node(double_linked* node);
            /**
             * create a double linked for user
             */
            double_linked* create_double_linked(void* data, int size);
            void _add_double_linked(double_linked* current, double_linked* pre, double_linked* next);
            /**
             * top add doulbe linked
             */
            int top_add_double_linked(void* data, int size, double_linked* header);
            /**
             * tail add double linked
             */
            int tail_add_double_linked(void* data, int size, double_linked* header);
            /**
             * print all data in double linked
             */
            void print_double_linked(double_linked* header, double_linked_print func);
            /**
             * empty all data in double linked
             */
            void empty_double_linked(double_linked* header);
            /**
             * delete a element in the double linked
             */
            void delete_double_linked(void* data, double_linked* header, double_linked_delete func);
            /**
             * free all data in the double linked
             */
            void free_double_linked(double_linked* header);
        #endif
    
    二、cat myerror.h
        #ifndef  _MYERROR_H
        #define  _MYERROR_H
    
        //serial error     1
        // error           2
        // warning         3
        // information     4
    
    
        #define    DEBUG1(...)      fprintf(stderr,"SERI ERR: " __VA_ARGS__);
        #define    DEBUG2(...)      fprintf(stderr,"ERR: " __VA_ARGS__);
        #define    DEBUG3(...)      fprintf(stdout,"WARNING: " __VA_ARGS__);
        #define    DEBUG4(...)      fprintf(stdout,"INFORMATION: " __VA_ARGS__);
        #define    DEBUG()            fprintf(stdout,"33[32mbug at func( %s ) : %d33[0m
    ", __func__, __LINE__);
    
    
        #define    ERR(lever ,con, ret , ...)        
           do                                        
            {                                        
                if(con)                                
                {                                    
                    DEBUG##lever(__VA_ARGS__)        
                    ret;                            
                }                                    
            }while(0)
    
        #endif  //_MYERROR_H
    
    三、cat doulbe_linked.c
        #include "double_linked.h"
        void init_double_linked_node(double_linked* node){
            node->next = node;
            node->pre = node;
            node->datap = NULL;
            node->size = 0;
        }
    
        int check_data_size(void* data, int size){
            return ((data != NULL) && (size > 0));
        }
        /**
         * create a double linked for user
         */
        double_linked* create_double_linked(void* data, int size){
            double_linked* header = malloc(sizeof(double_linked));
            ERR(1, NULL == header, goto err, "create double linked fail
    ");
            
            init_double_linked_node(header);
    
            if(check_data_size(data, size)){
                void* new_data = malloc(size);
                ERR(1, NULL == new_data, goto err, "create double linked data fail
    ");
                memcpy(new_data, data, size);
                header->size = size;
                header->datap = new_data;
            }
    
            return header;
        err:
            return NULL;
        }
        void _add_double_linked(double_linked* current, double_linked* pre, double_linked* next){
            pre->next = current;
            current->next = next;
            next->pre = current;
            current->pre = pre;
        }
        /**
         * top add doulbe linked
         */
        int top_add_double_linked(void* data, int size, double_linked* header){
            if(check_data_size(data, size)){
                double_linked* node = malloc(sizeof(double_linked));
                ERR(1, NULL == header, goto err, "create note fail.
    ");
    
                init_double_linked_node(node);
    
                void* new_data = malloc(size);
                ERR(1, NULL == new_data, goto err, "create note data fail.
    ");
                memcpy(new_data, data, size);
                node->size = size;
                node->datap = new_data;
                _add_double_linked(node, header, header->next);
                return 0;
            }
        err:
            return -1;
        }
        /**
         * tail add double linked
         */
        int tail_add_double_linked(void* data, int size, double_linked* header){
            if(check_data_size(data, size)){
                double_linked* node = malloc(sizeof(double_linked));
                ERR(1, NULL == header, goto err, "create note fail.
    ");
    
                init_double_linked_node(node);
    
                void* new_data = malloc(size);
                ERR(1, NULL == new_data, goto err, "create note data fail.
    ");
                memcpy(new_data, data, size);
                node->size = size;
                node->datap = new_data;
                _add_double_linked(node, header->pre, header);
                return 0;
            }
        err:
            return -1;
            
        }
        /**
         * print all data in double linked
         */
        void print_double_linked(double_linked* header, double_linked_print func){
            double_linked* tmp = header->next;
            while(tmp != header){
                func(tmp);
                tmp = tmp->next;
            }
        }
        void _delete_double_linked_node(double_linked* pre, double_linked* next){
            pre->next = next;
            next->pre = pre;
        }
        void delete_double_linked_node(double_linked* node){
            _delete_double_linked_node(node->pre, node->next);
            if(node->datap){
                free(node->datap);
            }
            init_double_linked_node(node);
            free(node);
        }
        /**
         * empty all data in double linked
         */
        void empty_double_linked(double_linked* header){
            double_linked* tmp = header->next;
            double_linked* pre = header;
            while(tmp != header){
                pre = tmp;
                tmp = tmp->next;
                delete_double_linked_node(pre);
            }
            init_double_linked_node(header);
            if(header->datap)
                free(header->datap);
            header->datap = NULL;
            header->size = 0;
        }
        /**
         * delete a element in the double linked
         */
        void delete_double_linked(void* data, double_linked* header, double_linked_delete func){
            double_linked* tmp = header->next;
            double_linked* pre = header;
            while(tmp != header){
                pre = tmp;
                tmp = tmp->next;
                if(func(data, pre)){
                    delete_double_linked_node(pre);
                }
            }
        }
        void free_double_linked(double_linked* header){
            double_linked* tmp = header->next;
            double_linked* pre = header;
            while(tmp != header){
                pre = tmp;
                tmp = tmp->next;
                delete_double_linked_node(pre);
            }
    
            init_double_linked_node(header);
            if(header->datap)
                free(header->datap);
            header->datap = NULL;
            header->size = 0;
            free(header);
        }
    
    四、cat main.c
        #include "double_linked.h"
    
        #define NR(x) ((sizeof(x))/sizeof(x[0]))
    
        /**
         * test struct
         */
        typedef struct STUDENT{
            int id;
            int score;
        }student;
    
        /**
         * callback function
         */
        void print(double_linked* node);
        int delete(void* data, double_linked* node);
    
        int main(int argc, char** argv){
            /**
             * demo data
             */
            student students[4] = {
                {1,1},
                {2,2},
                {2,2},
                {3,3},
            };
            double_linked* header = create_double_linked(NULL, 0);
    
            printf("--------------source--------------->
    ");
            int i = 0;
            for(i = 0; i < NR(students); i++){
                printf("student: id = %d, score = %d
    ", students[i].id, students[i].score);
            }
    
            printf("------------top add--------------->
    ");
            for(i = 0; i < NR(students); i++){
                top_add_double_linked(&students[i],sizeof(student), header);
            }
            print_double_linked(header, print);
    
            empty_double_linked(header);
    
            printf("-----------tail add-------------->
    ");
            for(i = 0; i < NR(students); i++){
                tail_add_double_linked(&students[i],sizeof(student), header);
            }
            print_double_linked(header, print);
    
            printf("-----------delete-------------->
    ");
            student stu = {2,2};
            delete_double_linked(&stu, header, delete);
            print_double_linked(header, print);
    
            printf("-------------free-------------->
    ");
            free_double_linked(header);
        }
        /**
         * impelement of the client print
         */
        void print(double_linked* node){
            student* stu = (student*)(node->datap);
            printf("student: id = %d, score = %d
    ", stu->id, stu->score);
        }
        /**
         * impelement of the client delete
         */
        int delete(void* data, double_linked* node){
            student* stu = (student*)(node->datap);
            return (((student*)data)->id == stu->id) && (((student*)data)->score == stu->score);
        }
  • 相关阅读:
    HDU1013 Digital Roots
    DP---背包问题
    新生代与老年代
    JVM常见问题(二)
    JVM常见问题 一(转载)
    JVM内存模型及分区
    (转载)JVM知识小集
    类加载机制:全盘负责和双亲委托
    mysql 函数GROUP_CONCAT(temp.amount SEPARATOR ',')的用法
    mysql优化--explain关键字
  • 原文地址:https://www.cnblogs.com/zengjfgit/p/5077050.html
Copyright © 2011-2022 走看看