• 双向链表


    #include <stdio.h>  
    #include <stdlib.h>  
    
    
    #if 1  
    typedef int (*fp_node_proc)(void* datap, void *cookie);  
    typedef int (*fp_node_cmp)(const void*, const void*);  
       
    struct node_st {  
        void *datap;  
        struct node_st *next, *prev;  
    };  
       
    struct llist_st {  
        struct node_st head;  
        int elmsize;  
        int elmnr;  
    };  
      
    void* llist_new(int elmsize)  
    {  
        struct llist_st *newlist;  
          
        newlist = (struct llist_st *)malloc(sizeof(struct llist_st));  
        if (newlist == NULL) {  
            return NULL;  
        }  
      
        newlist->head.datap = NULL;  
        newlist->head.next = &newlist->head;  
        newlist->head.prev = &newlist->head;  
        newlist->elmsize = elmsize;  
      
        return (void*)newlist;  
    }  
      
    int llist_destroy(void *llist)  
    {  
        struct llist_st *me = llist;  
        struct node_st *curr, *saved;  
      
        if (NULL == llist) return -1;  
        for ( curr = me->head.next ; curr != &me->head; curr = saved ) {  
            saved = curr->next;  
            free(curr->datap);  
            free(curr);  
        }  
      
        free(me);  
        return 0;  
    }  
      
    int llist_node_append(void *llist, const void *datap)  
    {  
        struct llist_st *me = llist;  
        struct node_st *newnodep;  
      
        newnodep = (struct node_st *)malloc(sizeof(struct node_st));  
        if (newnodep == NULL) {  
            return -1;  
        }  
          
        newnodep->datap = malloc(me->elmsize);  
        if (newnodep->datap == NULL) {  
            free(newnodep);  
            return -1;  
        }  
      
        // insert as last  
        memcpy(newnodep->datap, datap, me->elmsize);  
        newnodep->prev = me->head.prev;  
        newnodep->next = &me->head;  
        me->head.prev->next = newnodep;  
        me->head.prev = newnodep;  
      
        return 0;  
    }  
      
    int llist_node_insert(void* llist, const void* datap, fp_node_cmp comp)  
    {  
        struct llist_st *me = llist;  
        struct node_st *curr = NULL;  
        struct node_st *newnodep;  
      
        if (NULL == llist) return -1;  
        if (NULL == comp) return -1;  
      
        newnodep = (struct node_st *)malloc(sizeof(struct node_st));  
        if (newnodep == NULL) {  
            return -1;  
        }  
        newnodep->datap = malloc(me->elmsize);  
        if (newnodep->datap == NULL) {  
            free(newnodep);  
            return -1;  
        }  
        memcpy(newnodep->datap, datap, me->elmsize);  
      
        for ( curr = me->head.next; curr != &me->head; curr = curr->next ) {  
            if ( comp(curr->datap, datap) > 0 ) {  
                // insert before curr, maybe as first  
                newnodep->next = curr;  
                newnodep->prev = curr->prev;  
                curr->prev->next = newnodep;  
                curr->prev = newnodep;  
                return 0;  
            }  
        }  
      
        // insert as last  
        newnodep->next = &me->head;  
        newnodep->prev = me->head.prev;  
        me->head.prev->next = newnodep;  
        me->head.prev = newnodep;  
          
        return 0;  
    }  
      
    void *llist_node_delete(void* llist, const void *key, fp_node_cmp comp)  
    {  
        struct llist_st *me = llist;  
        struct node_st *curr = NULL;  
      
        if (NULL == llist) return NULL;  
        if (NULL == comp) return NULL;  
      
        for ( curr = me->head.next; curr != &me->head; curr = curr->next) {  
            if ( comp(curr->datap, key) == 0 ) {  
                curr->prev->next = curr->next;  
                curr->next->prev = curr->prev;  
                return curr->datap;  
            }  
        }  
          
        return NULL;  
    }  
      
    // if proc return !0, then break the travel  
    int llist_travel(void* llist, fp_node_proc proc, void *cookie)  
    {  
        struct llist_st *me = (struct llist_st *)llist;  
        struct node_st *curr;  
      
        if (NULL == llist) return -1;  
        if (NULL == proc) return -1;  
          
        for ( curr = me->head.next; curr != &me->head; curr = curr->next ) {  
            if ( 0 != proc(curr->datap, cookie) ) {  
                break;  
            }  
        }  
          
        return 0;  
    }  
      
    void* llist_node_find(void *llist, fp_node_cmp comp, const void *key)  
    {  
        struct llist_st *me = llist;  
        struct node_st *curr;  
      
        if (NULL == llist) return NULL;  
        if (NULL == comp) return NULL;  
      
        for ( curr = me->head.next; curr != &me->head; curr = curr->next ) {  
            if ( comp(curr->datap, key) == 0 ) {  
                return curr->datap;  
            }  
        }  
          
        return NULL;  
    }  
      
    int llist_sort(void* llist, fp_node_cmp comp)  
    {  
        struct llist_st *me = llist;  
        struct node_st *curr;  
        struct node_st *ptr, *saved;  
        struct node_st temp_head;  
      
        if (NULL == llist) return -1;  
        if (NULL == comp) return -1;  
      
        temp_head.prev = &temp_head;  
        temp_head.next = &temp_head;  
          
        for (curr = me->head.next; curr != &me->head; curr = saved) {  
            saved = curr->next;  
            for (ptr = temp_head.next; ptr != &temp_head; ptr = ptr->next) {  
                if ( comp(ptr->datap, curr->datap) > 0 ) {  
                    // insert before curr, maybe as first  
                    curr->next = ptr;  
                    curr->prev = ptr->prev;  
                    ptr->prev->next = curr;  
                    ptr->prev = curr;  
                    break;  
                }  
            }  
      
            // insert as last  
            if ( ptr == &temp_head ){  
                curr->next = &temp_head;  
                curr->prev = temp_head.prev;  
                temp_head.prev->next = curr;  
                temp_head.prev = curr;  
            }  
        }  
      
        me->head.next = temp_head.next;  
        me->head.prev = temp_head.prev;  
        temp_head.next->prev = &me->head;  
        temp_head.prev->next = &me->head;  
              
        return 0;  
    }  
    #endif

    测试代码:

    #include <stdio.h>  
    #include <stdlib.h>  
    
    
    typedef struct tagUSER_DATA_ST  
    {  
        int key;  
        int param;  
    }USER_DATA_ST;  
      
    int node_print(void* datap, void *cookie)  
    {  
        USER_DATA_ST *ptr = (USER_DATA_ST *)datap;  
        printf("%d(%d) ", ptr->key, ptr->param);  
        return 0;  
    }  
      
    int node_cmp(const void* data1, const void* data2)  
    {  
        USER_DATA_ST *ptr1 = (USER_DATA_ST *)data1;  
        USER_DATA_ST *ptr2 = (USER_DATA_ST *)data2;  
        return (ptr1->key - ptr2->key);  
    }  
      
    int main()  
    {  
        int i;  
        USER_DATA_ST temp;  
        USER_DATA_ST *ptr;  
        USER_DATA_ST *my_llist = llist_new(sizeof(USER_DATA_ST));  
      
        printf("
     init  : ");  
        srand(0);  
        for(i = 10; i > 0; i--) {  
            temp.key = i;  
            temp.param = rand()%100;  
            llist_node_append(my_llist, &temp);  
        }  
        llist_travel(my_llist, node_print, NULL);  
      
        printf("
     delete: ");  
        temp.key = 0; llist_node_delete(my_llist, &temp, node_cmp);  
        temp.key = 3; llist_node_delete(my_llist, &temp, node_cmp);  
        temp.key = 5; llist_node_delete(my_llist, &temp, node_cmp);  
        temp.key = 8; llist_node_delete(my_llist, &temp, node_cmp);  
        llist_travel(my_llist, node_print, NULL);  
      
        printf("
     find  : ");  
        temp.key = 3; ptr = llist_node_find(my_llist, node_cmp, &temp);  
        if(NULL != ptr) printf("
     find error");  
        temp.key = 4; ptr = llist_node_find(my_llist, node_cmp, &temp);  
        if(NULL == ptr) printf("
     find error");  
        node_print(ptr, NULL);  
      
        printf("
     sort  : ");  
        llist_sort(my_llist, node_cmp);  
        llist_travel(my_llist, node_print, NULL);  
      
        printf("
     insert: ");  
        temp.key = 0; temp.param = 111;  
        llist_node_insert(my_llist, &temp, node_cmp);  
        temp.key = 5; temp.param = 222;  
        llist_node_append(my_llist, &temp);  
        temp.key = 20; temp.param = 333;  
        llist_node_insert(my_llist, &temp, node_cmp);  
        llist_travel(my_llist, node_print, NULL);  
      
        printf("
     sort  : ");  
        llist_sort(my_llist, node_cmp);  
        llist_travel(my_llist, node_print, NULL);  
      
        printf("
     destroy: ");  
        llist_destroy(my_llist);  
          
        return 0;  
    }  
  • 相关阅读:
    阶段3 2.Spring_09.JdbcTemplate的基本使用_2 JdbcTemplate的概述和入门
    阶段3 2.Spring_08.面向切面编程 AOP_10 总结和作业安排
    阶段3 2.Spring_08.面向切面编程 AOP_9 spring基于注解的AOP配置
    阶段3 2.Spring_08.面向切面编程 AOP_8 spring中的环绕通知
    阶段3 2.Spring_08.面向切面编程 AOP_7 通用化切入点表达式
    阶段3 2.Spring_08.面向切面编程 AOP_6 四种常用通知类型
    阶段3 2.Spring_08.面向切面编程 AOP_5 切入点表达式的写法
    阶段3 2.Spring_08.面向切面编程 AOP_4 spring基于XML的AOP-配置步骤
    阶段3 2.Spring_08.面向切面编程 AOP_3 spring基于XML的AOP-编写必要的代码
    阶段3 2.Spring_08.面向切面编程 AOP_2 spring中的aop术语和细节
  • 原文地址:https://www.cnblogs.com/soul-stone/p/6852277.html
Copyright © 2020-2023  润新知