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;
    short int type;
    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,size_t size,bool direct);
int listDelNode(listNode *nd);
#endif

2.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;
    }
}
int main(void)
{
    printf("@=1\n\n");
    list *a0=listCreate(true);
    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;
}

有不足之处,请大家多指教

时间: 2024-10-16 10:19:36

C 双向链表的实现的相关文章

数据结构第四篇——线性表的链式存储之双向链表

?注:未经博主同意,不得转载. 前面讨论的单链表,每个结点中只有一个指针域,用来存放指向后继结点的指针,因此,从某个结点出发只能顺时针往后查找其他结点.若要查找某个结点的直接前驱,则需要从头指针开始沿链表探寻,处理起来十分不方便.为克服单链表的这一缺点,可引入双向链表. 双向链表中每一个结点含有两个指针域,一个指针指向其直接前驱结点,另一个指针指向直接后继结点.和单链表类似,双向链表一般也只有头指针唯一确定:同样也可设头结点,使得双向链表的某些操作简便一些. 双向链表结构定义如下:  双向链表是

双向链表(一)

参考: http://blog.sina.com.cn/s/blog_7d44748b01013fsf.html    (写的太好啦) http://blog.163.com/haibianfeng_yr/blog/static/34572620201453061036702/ 双(向)链表中有两条方向不同的链,即每个结点中除next域存放后继结点地址外,还增加一个指向其直接前趋的指针域prior.双向链表在查找时更方便 特别是大量数据的遍历 注意:    ①双链表由头指针head惟一确定的. 

c语言双向链表

typedef int ElemType; typedef struct _Node { ElemType value; struct _Node* pnext; struct _Node* prev; }node, *pNode; //创建双向链表 pNode Create_Double_List(int count) { pNode pn = NULL; pNode pb = NULL; pNode phead = (pNode)malloc(sizeof(node)); printf("请

C++__双向链表(练习)

双向链表 link.h #ifndef LINK_H_ #define LINK_H_ #define HEADER 0 #define TAIL -1 typedef int data_type; enum LINK_OP { LINK_ERR = -1, LINK_OK }; class LINK { private: data_type data; LINK *next; LINK *last; public: LINK(); LINK(data_type data); virtual ~

剑指offer:二叉搜索树与双向链表

1.题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 2.解题思路: (1)将左子树构造成双向链表,并返回链表头节点: (2)定位左子树双链表的尾节点: (3)如果左子树链表不为空,将当前root连缀其链尾: (4)将右子树构造出双向链表,并返回链表头节点: (5)如果右子树链表不为空,将当前root连缀其表头: (6)根据左子树链表是否为空,确定返回的节点. 3.JavaScript实现: function Conv

Uva 12657 Boxes in a Line 双向链表

操作4比较特殊,为了避免一次性修改所有元素的指针,由于题目只要求输出奇数盒子的编号,所以我们可以灵活的根据是否进行过操作4对操作1 操作2 进行改动 操作3不受操作4影响 上代码.... #include<cstdio> #include<algorithm> const int maxn=100000+5; int right[maxn],left[maxn]; void link (int L,int R){ right[L]=R;left[R]=L; } //在双向链表这样复

双向链表 Boxes in a Line UVA - 12657

首先记录一下对链表的理解,最初看链表是在教材上看的,上面是用结构体, 理解起来还不是很困难,我也以为自己懂了,然而看到紫书上链表用的是数组(UVA11988),真的是..到最后把他的代码背下来了都还是有点晕(/(ㄒoㄒ)/~~),那个时候做题有点匆忙,也就没深究,不过后面那道(也就是这道)也就没再写了,差不多隔了一个月吧,有那么一点点感觉就是这次没看代码自己写过一遍后. 单向每一个结构体有两个元素(或者更多),其中一个是下一个元素的地址,其他的是他本身有的东西,在这道题中,1 2 3 4 5,

Shuffling Machine和双向链表

1. 双向链表 https://github.com/BodhiXing/Data_Structure 2. Shuffling Machine https://pta.patest.cn/pta/test/17/exam/4/question/264 思路: 代码: 1 #include <iostream> 2 using namespace std; 3 4 #define MAXCARD 54 5 6 string int2str(int x) 7 { 8 char ch[4]; 9

二叉搜索树与双向链表

void convertNode(BSTreeNode *root, BSTreeNode ** pLastNodeInList) { if(!root) return ; if(root->left) { convertNode(root->left, pLastNodeInList); } root->left = *pLastNodeInList; if(*pLastNodeInList != NULL) (*pLastNodeInList)->right = root; *

数据结构 线性双向链表

//线性双向链表 #ifndef _MY_DLINKLIST_H_ #define _MY_DLINKLIST_H_ typedef void DLinkList; typedef struct _tag_DLinkListNode { struct _tag_DLinkListNode* next; struct _tag_DLinkListNode * pre; }DLinkListNode; //创建双向链表 DLinkList* DLinkList_Create(); //销毁双向链表