C 双向链表的实现

rlist.h代码

#ifndef __LIST_H
#define __LIST_H
#include <stdbool.h>
#include <pthread.h>
#define UT_BASE(TYPE)          \
    struct {                   \
        TYPE *prev;            \
        TYPE *next;            \
    }
#define listSize(p)  (p->listlen)
#define nodeSize(p)  (p->nodelen)
#define listHead(p)  (p->head)
#define listTail(p)  (p->tail)
typedef struct listNode{
    struct listNode *prev;
    struct listNode *next;
    size_t size;
    char buf[];
}listNode;
typedef struct list
{
    unsigned long nodelen;
    listNode *head;
    listNode *tail;
    UT_BASE(struct list) base;
    pthread_mutex_t lock;
}list;
typedef struct listmgr
{
    unsigned int listlen;
    list *head;
    list *tail;
    pthread_mutex_t lock;
}listmgr;
/*
 *date:2015-08-29
 *author:zhoulin
 *function:create a double link list
 *parameter:
 *  direct:if true,add list to head
 */
list *listCreate(bool direct);
int listRelease(list *lt);
listNode *listAddNode(list *lt,void *data,size_t size,bool direct);
int listDelNode(list *lt,listNode *nd);
#endif

rlist.c代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rlist.h"
static listmgr *mgr=NULL;
list * listCreate(bool direct)
{  
#ifdef INFO
    printf("  ****************Enter listCreate(bool =%d)****************\n",direct);
#endif
    list *cur;
    if(!mgr){
         mgr=(listmgr *)malloc(sizeof(*mgr));
         pthread_mutex_init(&mgr->lock,NULL);
         mgr->listlen=0;
     }
     if(!(cur=(list *)malloc(sizeof(*cur))))
            return NULL;
     if(!mgr->head){
         pthread_mutex_lock(&mgr->lock);
         cur->base.prev=cur->base.next=NULL;
         mgr->head=mgr->tail=cur;
         ++mgr->listlen;
         pthread_mutex_unlock(&mgr->lock);
     }
     else{
         if(direct){
             cur->base.prev=mgr->head->base.prev;
             cur->base.next=mgr->head;
             mgr->head->base.prev=cur;
             mgr->head=cur;
         }
         else{
             cur->base.next=mgr->tail->base.next;
             mgr->tail->base.next=cur;
             cur->base.prev=mgr->tail;
             mgr->tail=cur;
         }
         pthread_mutex_lock(&mgr->lock);
         ++mgr->listlen;
         cur->nodelen=0;
         cur->head=cur->tail=NULL;
         pthread_mutex_unlock(&mgr->lock);
     }
#ifdef INFO
        printf("        ->add list =%p\n",cur);
#endif
    return cur;
}
int  listRelease(list *lt)
{
#ifdef INFO
    printf("  ****************Enter listRelease(list =%p)****************\n\n",lt);
#endif
    if(!mgr){return 1;}
    if(!lt){return 1;}
    if(mgr->listlen<=0){return 1;}
    if(lt->base.prev&&lt->base.next){
        lt->base.prev->base.next=lt->base.next;
        lt->base.next->base.prev=lt->base.prev;
    }
    else if(!lt->base.prev&&lt->base.next){
        mgr->head=lt->base.next;
        mgr->head->base.prev=NULL;
    }
    else if(lt->base.prev&&!lt->base.next){
        mgr->tail=lt->base.prev;
        mgr->tail->base.next=NULL;
    }
    else{
        mgr->head=mgr->tail=NULL;
    }
    lt->head=lt->tail=NULL;
    lt->base.prev=lt->base.next=NULL;
    listNode *nd=lt->head;
    while(nd!=NULL)
    {
        listNode *nd_next=nd->next;
        free(nd);
        nd=nd_next;
    }
    free(lt);
    lt=NULL;
    pthread_mutex_lock(&mgr->lock);
    --mgr->listlen;
    pthread_mutex_unlock(&mgr->lock);
    return  0;
}
void listPrt(listmgr *mgr)
{
#ifdef INFO
    printf("  ****************Enter listPrt(listmgr =%p)****************\n",mgr);
    printf("    mgr->head =%p,mgr->tail =%p,mgr->listlen =%d\n",mgr->head,mgr->tail,mgr->listlen);
#endif
    list *lt=mgr->head;
    while(lt!=NULL)
    {
#ifdef INFO
        printf("    current list =%p,node of len=%d,prev = %p,next =%p\n",lt,lt->nodelen,lt->base.prev,lt->base.next);
#endif
        listNode *lnd=lt->head;
        while(lnd!=NULL)
        {
#ifdef INFO
            printf("      listNode =%p,prev = %p,next =%p\n",lnd,lnd->prev,lnd->next);
#endif
            lnd=lnd->next;
        }
        lt=lt->base.next;
    }
}
void listDestroy(listmgr *mgr)
{
#ifdef INFO
    printf("  ****************Enter listDestroy(listmgr =%p)****************\n",mgr);
#endif
    list *lt=mgr->head;
    while(lt!=NULL)
    {
        list *lt_next=lt->base.next;
        listNode *tmp=lt->head;
#ifdef INFO
        printf("    ##free list = %p\n",lt);
#endif
        while(tmp!=NULL)
        {
            listNode *t=tmp->next;
#ifdef INFO
            printf("        ->free listNode =%p\n",tmp);
#endif
            free(tmp);
            tmp=t;

       }
        free(lt);
        lt=lt_next;
    }
}
listNode *listAddNode(list *lt,void *data,size_t size,bool direct)
{
    printf("  ****************listAddNode(list =%p,data=%p,size =%d,direct =%d)****************\n",lt,data,size,direct);
    listNode *cur=NULL;
    if(!lt||size<=0){return NULL;}
    if((cur=(listNode *)malloc(sizeof(*cur)+size))==NULL){
        return NULL;
    }
    memset((char *)&cur->buf,'\0',size);
    cur->size=size;
    memcpy((char *)&cur->buf,data,size);
    printf("        listNode =%p,buf =%p\n",cur,cur->buf);
    if(!lt->head){
        cur->prev=cur->next=NULL;
        lt->head=lt->tail=cur;
    }
    else{
        if(direct){
            cur->prev=NULL;
            cur->next=lt->head;
            lt->head->prev=cur;
            lt->head=cur;
        }
        else{
            cur->next=NULL;
            lt->tail->next=cur;
            cur->prev=lt->tail;
            lt->tail=cur;
        }
    }
    pthread_mutex_lock(&lt->lock);
    ++lt->nodelen;
    pthread_mutex_unlock(&lt->lock);
    return cur;
}
int listDelNode(list *lt,listNode *nd)
{
    if(!lt||!nd){return 1;}
    return 0;
}
int main(void)
{
    printf("@=1\n\n");
    list *a0=listCreate(true);
    int i=100;
    long x=2000;
    char c='A';
    listNode *n1=listAddNode(a0,(char *)&i,4,true);
    listNode *n2=listAddNode(a0,(char *)&x,8,false);
    listNode *n3=listAddNode(a0,(char *)&c,1,true);
    printf("n1->buf =%d\n",*(int  *)n1->buf);
    printf("n2->buf =%ld\n",*(long  *)n2->buf);
    printf("n3->buf =%c\n",*(char  *)n3->buf);
    listPrt(mgr);
    listRelease(a0);
    listPrt(mgr);
    printf("@=2 head\n\n");
    list *a1=listCreate(false);
    list *a2=listCreate(true);
    listPrt(mgr);
    listRelease(a2);
    listPrt(mgr);
    printf("@=2 tail\n\n");
    a2=listCreate(true);
    listPrt(mgr);
    listRelease(a1);
    listPrt(mgr);
    printf("@>2 \n\n");
    a1=listCreate(false);
    list *a4=listCreate(true);
    list *a5=listCreate(false);
    list *a6=listCreate(true);
    listPrt(mgr);
    listRelease(a4);
    listPrt(mgr);
    listDestroy(mgr);
    return 0;
}

 运行结果:

[mysql@centos2 sredis]$ ./rlist
@=1

  ****************Enter listCreate(bool =1)****************
        ->add list =0x218d060
  ****************listAddNode(list =0x218d060,data=0x7ffdce89ff74,size =4,direct =1)****************
        listNode =0x218d0c0,buf =0x218d0d8
  ****************listAddNode(list =0x218d060,data=0x7ffdce89ff68,size =8,direct =0)****************
        listNode =0x218d0f0,buf =0x218d108
  ****************listAddNode(list =0x218d060,data=0x7ffdce89ff67,size =1,direct =1)****************
        listNode =0x218d120,buf =0x218d138
n1->buf =100
n2->buf =2000
n3->buf =A
  ****************Enter listPrt(listmgr =0x218d010)****************
    mgr->head =0x218d060,mgr->tail =0x218d060,mgr->listlen =1
    current list =0x218d060,node of len=3,prev = (nil),next =(nil)
      listNode =0x218d120,prev = (nil),next =0x218d0c0
      listNode =0x218d0c0,prev = 0x218d120,next =0x218d0f0
      listNode =0x218d0f0,prev = 0x218d0c0,next =(nil)
  ****************Enter listRelease(list =0x218d060)****************

  ****************Enter listPrt(listmgr =0x218d010)****************
    mgr->head =(nil),mgr->tail =(nil),mgr->listlen =0
@=2 head

  ****************Enter listCreate(bool =0)****************
        ->add list =0x218d060
  ****************Enter listCreate(bool =1)****************
        ->add list =0x218d150
  ****************Enter listPrt(listmgr =0x218d010)****************
    mgr->head =0x218d150,mgr->tail =0x218d060,mgr->listlen =2
    current list =0x218d150,node of len=0,prev = (nil),next =0x218d060
    current list =0x218d060,node of len=0,prev = 0x218d150,next =(nil)
  ****************Enter listRelease(list =0x218d150)****************

  ****************Enter listPrt(listmgr =0x218d010)****************
    mgr->head =0x218d060,mgr->tail =0x218d060,mgr->listlen =1
    current list =0x218d060,node of len=0,prev = (nil),next =(nil)
@=2 tail

  ****************Enter listCreate(bool =1)****************
        ->add list =0x218d150
  ****************Enter listPrt(listmgr =0x218d010)****************
    mgr->head =0x218d150,mgr->tail =0x218d060,mgr->listlen =2
    current list =0x218d150,node of len=0,prev = (nil),next =0x218d060
    current list =0x218d060,node of len=0,prev = 0x218d150,next =(nil)
  ****************Enter listRelease(list =0x218d060)****************

  ****************Enter listPrt(listmgr =0x218d010)****************
    mgr->head =0x218d150,mgr->tail =0x218d150,mgr->listlen =1
    current list =0x218d150,node of len=0,prev = (nil),next =(nil)
@>2 

  ****************Enter listCreate(bool =0)****************
        ->add list =0x218d060
  ****************Enter listCreate(bool =1)****************
        ->add list =0x218d1b0
  ****************Enter listCreate(bool =0)****************
        ->add list =0x218d210
  ****************Enter listCreate(bool =1)****************
        ->add list =0x218d270
  ****************Enter listPrt(listmgr =0x218d010)****************
    mgr->head =0x218d270,mgr->tail =0x218d210,mgr->listlen =5
    current list =0x218d270,node of len=0,prev = (nil),next =0x218d1b0
    current list =0x218d1b0,node of len=0,prev = 0x218d270,next =0x218d150
    current list =0x218d150,node of len=0,prev = 0x218d1b0,next =0x218d060
    current list =0x218d060,node of len=0,prev = 0x218d150,next =0x218d210
    current list =0x218d210,node of len=0,prev = 0x218d060,next =(nil)
  ****************Enter listRelease(list =0x218d1b0)****************

  ****************Enter listPrt(listmgr =0x218d010)****************
    mgr->head =0x218d270,mgr->tail =0x218d210,mgr->listlen =4
    current list =0x218d270,node of len=0,prev = (nil),next =0x218d150
    current list =0x218d150,node of len=0,prev = 0x218d270,next =0x218d060
    current list =0x218d060,node of len=0,prev = 0x218d150,next =0x218d210
    current list =0x218d210,node of len=0,prev = 0x218d060,next =(nil)
  ****************Enter listDestroy(listmgr =0x218d010)****************
    ##free list = 0x218d270
    ##free list = 0x218d150
    ##free list = 0x218d060
    ##free list = 0x218d210

 

posted @ 2015-08-28 20:32  一个万能盒子叫数据库  阅读(245)  评论(0编辑  收藏  举报