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

    /**************************************************************************
     *            Linux C single linked for any data type
     * 声明:
     *      提供一种单链接口,可以保存保存任何类型的数据,有时候这种需求在
     *  很多场合还是会用到的。
     *                  
     *                                  2015-7-5 晴 深圳 南山平山村 曾剑锋
     *************************************************************************/
    
                    \\\\-*- 目录 -*-/////////
                    |  一、cat single_linked.h
                    |  二、cat myerror.h
                    |  三、cat single_linked.c
                    |  四、cat main.c
                    \\\\\\\//////////////
    
    一、cat single_linked.h
        #ifndef __SINGLE_LINKED_H__
            #define __SINGLE_LINKED_H__
        
            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            #include "myerror.h"
            
            typedef struct SINGLE_LINKED{
                void* datap;
                int size;
                struct SINGLE_LINKED* next;
            } single_linked;
        
            typedef void (*single_linked_print)(void* data);
            typedef int (*single_linked_delete)(void* data, void* linked_delete);
            /**
             * you should giving a vilid data dan size for save
             */
            int check_data_size(void *data, int size);
            /**
             * create a single linked header
             */
            single_linked* create_single_linked(void* data, int size);
            /**
             * add data to single linked at top
             */
            int top_add_single_linked(void* data, int size, single_linked* header);
            /**
             * add data to single linked at tail
             */
            int tail_add_single_linked(void* data, int size, single_linked* header);
            /**
             * delete data in single linked 
             */
            int delete_single_linked(void* data, single_linked* header, single_linked_delete func);
            /**
             * print all data in single linked
             */
            void print_single_linked(single_linked* header, single_linked_print func);
            /**
             * empty the single linked
             */
            void empty_single_linked(single_linked* header);
            /**
             * free all data in single linked
             */
            void free_single_linked(single_linked* header);
        #endif  //__SINGLE_LINKED_H__
    
    二、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 single_linked.c
        #include "single_linked.h"
        /**
         * create a single linked as header
         */
        single_linked* create_single_linked(void *data, int size){
            single_linked* header = malloc(sizeof(single_linked));
            ERR(1, NULL == header, goto err; "create single linked header fail.
    ");
            header->next = NULL;
            header->datap = NULL;
            header->size = 0;
            
            if(check_data_size(data,size)){
                void* new_data = malloc(size);
                ERR(1, NULL == new_data, goto new_data_err; "create single linked header with data fail.
    ");
                memcpy(new_data, data, size);
                header->size = size;
                header->datap = new_data;
            }
            return header;
        new_data_err:
            free(header);
        err:
            return NULL;
        }
        
        int check_data_size(void* data, int size){
            return ((data != NULL) && (size > 0));
        }
        
        int top_add_single_linked(void* data, int size, single_linked* header){
            ERR(1, NULL == header, return -1, "the header was NULL in top add single linked
    ");
            single_linked* new_node = NULL;
        
            if(check_data_size(data, size)){
                single_linked* new_node = malloc(sizeof(single_linked));
                ERR(1, NULL == new_node, goto err; "top add malloc node fail.
    ");
                new_node->next = NULL;
                new_node->datap = NULL;
                new_node->size = 0;
        
                void* new_data = malloc(size);
                ERR(1, NULL == new_data, goto err1; "top add malloc data fail.
    ");
                memcpy(new_data, data, size);
                new_node->size = size;
                new_node->datap = new_data;
        
                new_node->next = header->next;
                /**
                 * I had pazzled at this point with (header->next = new_node->next)
                 */
                header->next = new_node;
                
            }   
            return 0;
        err1:
            free(new_node);
        err:
            return -1;
        }
        
        /**
         * add data to single linked at tail
         */
        int tail_add_single_linked(void* data, int size, single_linked* header){
            ERR(1, NULL == header, return -1, "the header was NULL in tail add single linked
    ");
            single_linked* new_node = NULL;
        
            if(check_data_size(data, size)){
                single_linked* new_node = malloc(sizeof(single_linked));
                ERR(1, NULL == new_node, goto err; "top add malloc node fail.
    ");
                new_node->next = NULL;
                new_node->datap = NULL;
                new_node->size = 0;
        
                void* new_data = malloc(size);
                ERR(1, NULL == new_data, goto err1; "top add malloc data fail.
    ");
                memcpy(new_data, data, size);
                new_node->size = size;
                new_node->datap = new_data;
        
                //new_node->next = header->next;
                while(header->next)
                    header = header->next;
                /**
                 * I had pazzled at this point with (header->next = new_node->next)
                 */
                header->next = new_node;
            }   
            return 0;
        err1:
            free(new_node);
        err:
            return -1;
        }
        
        /**
         * delete data in single linked 
         */
        int delete_single_linked(void* data, single_linked* header, single_linked_delete func){
            ERR(1, ((NULL == data) || (NULL == header) || (NULL == func)), return; "you shouldn't giving NULL for delete single linkde
    ");
        
            single_linked* tmp = header->next;
            single_linked* pre = header;
            while(tmp){
                /**
                 * you should giving a return value to decision delete this or not
                 */
                if(func(data, tmp->datap)){
                    pre->next = tmp->next;
                    tmp->next = NULL;
                    free(tmp->datap);
                    free(tmp);
                    tmp = pre->next;
                }else{
                    pre = tmp;
                    tmp = tmp->next;
                }
            }
            return 0;
        }
        
        /**
         * print all data in single linked
         */
        void print_single_linked(single_linked* header, single_linked_print func){
            ERR(1, ((NULL == header) || (NULL == func)), return; "you shouldn't giving NULL for print single linkde
    ");
            single_linked* tmp = header->next;
            while(tmp){
                func(tmp);
                tmp = tmp->next;
            }
        }
        
        /**
         * free all data in single linked
         */
        void free_single_linked(single_linked* header){
            ERR(1, NULL == header, return; "free a header with NULL
    ");
        
            single_linked* tmp = header->next;
            single_linked* pre = header->next;
            while(tmp){
                pre = tmp;
                tmp = tmp->next;
                free(pre->datap);
                free(pre);
            }
        
            if(header->datap != NULL){
                free(header->datap);
                header->datap = NULL;
            }
            header->next = NULL;
            free(header);
            header == NULL;
        }
        
        void empty_single_linked(single_linked* header){
            ERR(1, NULL == header, return, "empty header was NULL
    ");
        
            single_linked* tmp = header->next;
            single_linked* pre = header->next;
            while(tmp){
                pre = tmp;
                tmp = tmp->next;
                free(pre->datap);
                free(pre);
            }
        
            if(header->datap != NULL){
                free(header->datap);
                header->datap = NULL;
            }
            header->next = NULL;
            header->size = 0;
        }
    
    四、cat main.c
        #include "single_linked.h"
        
        #define NR(x) ((sizeof(x))/sizeof(x[0]))
        
        /**
         * test struct
         */
        typedef struct STUDENT{
            int id;
            int score;
        }student;
        
        /**
         * callback function
         */
        void print(void* data);
        int delete(void* data, void* linked_data);
        
        int main(int argc, char** argv){
            /**
             * demo data
             */
            student students[4] = {
                {1,1},
                {2,2},
                {2,2},
                {3,3},
            };
        
            single_linked* header = create_single_linked(NULL, 0);
        
            int i = 0;
            printf("--------------source------------------>
    ");
            for(i = 0; i < NR(students); i++){
                printf("student: id = %d, score = %d 
    ", students[i].id, students[i].score);
            }
        
            printf("--------------tail add---------------->
    ");
            for(i = 0; i < NR(students); i++){
                //top_add_single_linked(&students[i], sizeof(student), header);
                tail_add_single_linked(&students[i], sizeof(student), header);
            }
            print_single_linked(header, print);
        
            empty_single_linked(header);
        
            printf("--------------top add---------------->
    ");
            for(i = 0; i < NR(students); i++){
                //top_add_single_linked(&students[i], sizeof(student), header);
                top_add_single_linked(&students[i], sizeof(student), header);
            }
            print_single_linked(header, print);
        
            printf("--------------delete---------------->
    ");
            student stu = {2,2};
            delete_single_linked(&stu, header, delete);
            print_single_linked(header, print);
        
            printf("---------------free----------------->
    ");
            free_single_linked(header);
        }
        
        void print(void* data){
            student* stu = (((single_linked*)data)->datap);
            printf("student: id = %d, score = %d 
    ", stu->id, stu->score);
        }
        
        int delete(void* data, void* linked_data){
            return (((student*)data)->id == ((student*)linked_data)->id) && (((student*)data)->score == ((student*)linked_data)->score); 
        }
  • 相关阅读:
    递归算法解析成树形结构
    Tomcat性能参数设置
    hibernate.cfg.xml 配置(摘录)
    OpenCms 集成外部Solr Server
    安装配置OPENCMS的Replication cluster(从)详细过程
    ruby 格式化当前日期时间
    Ruby 语法快速入门
    ruby condition
    配置 RAILS FOR JRUBY1.7.4
    我的权限系统设计实现MVC4 + WebAPI + EasyUI + Knockout(五)框架及Web项目的组件化
  • 原文地址:https://www.cnblogs.com/zengjfgit/p/4622200.html
Copyright © 2011-2022 走看看