C语言实现双向链表[上]

来源:互联网 发布:画路线图的软件 编辑:程序博客网 时间:2024/04/27 23:35

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。

所以,从双向链表中的任意一结点开始,都可以很方便地访问它的前驱结点和后继结点。

在C里面有两种类型的双向链表,我把它们分别叫做环类型(ring style)与线性类型(linear style)。

网上大部分搜索到的都是双向循环链表的实现代码,具体见下篇。

上篇主要实现的是带有头结点的双向链表。主要函数代码如下:

typedef int ElemType;typedef struct DuLNode{ ElemType data;DuLNode *prior,*next;}DuLNode,*DuLinkList;//创建带有头结点的线性双向链表void InitList(DuLinkList *L){*L = (DuLinkList)malloc(sizeof(DuLNode));if(NULL != (*L))(*L)->prior = (*L)->next = NULL;elseexit(0);}//清空链表void ClearList(DuLinkList L){DuLinkList p = L->next;DuLinkList q;while(p != NULL){q = p->next;free(p);p = q;}L->prior = L->next = NULL;}//销毁双向链表void DestroyList(DuLinkList *L){DuLinkList p = (*L)->next;DuLinkList q;while(p != NULL){q = p->next;free(p);p = q;}free(*L);*L = NULL;}//判断表是否为空int ListEmpty(DuLinkList L){if(L->next == NULL)return true;elsereturn false;}//返回表的长度int ListLength(DuLinkList L){int len = 0;DuLinkList p = L->next;  //p指向第一个结点while(p != NULL){len++;p = p->next;}return len;}//返回第i个元素的值int GetElem(DuLinkList L,int i,ElemType* e){int j = 1;DuLinkList p = L->next;  //p指向第一个结点while(p != NULL && j < i) //顺指针向后查找,直到p指向第i个元素{j++;p = p->next;}if(p != NULL || j < i)return -1;*e = p->data;return 0;}//返回第i个元素的地址DuLinkList GetElemP(DuLinkList L,int i){int j = 0;DuLinkList p = L;  //p指向头结点if(i < 0 || i > ListLength(L))return NULL;for(j = 1; j <= i; j++)  //p指向第i个结点p = p->next;  //p指向下一个结点return p;}//在表的第i个位置之前插入元素eint ListInsert(DuLinkList L,int i,ElemType e){DuLinkList p,s;if(i < 1 || i > ListLength(L) +1)return -1;p = GetElemP(L,i-1);  //在L中确定第i个结点前驱的位置指针pif(!p)return -1;s = (DuLinkList)malloc(sizeof(DuLNode));if(!s)return -1;if(i == ListLength(L) +1)  //在最后一个结点后面插入元素{s->data = e;s->next = NULL;s->prior = p;p->next = s;}else{s->data = e;       //将e赋给新的结点s->prior = p;      //新结点的前驱为第i-1个结点s->next = p->next; //新结点的后继为第i个结点p->next->prior = s;//第i个结点的前驱指向新结点p->next = s;       //第i-1个结点的后继指向新结点}return 0;}//删除第i个结点int ListDelete(DuLinkList L, int i, ElemType *e){DuLinkList p;if(i < 1 || i > ListLength(L))return -1;p = GetElemP(L,i);  //在L中确定第i个元素的位置指针if(!p)return -1;*e = p->data;//把第i个结点的元素的值赋给eif(i == ListLength(L)) //删除最后一个结点的情况{p->prior->next = NULL;free(p);p = NULL;}else{p->prior->next = p->next;//第原i-1个结点的后继指向原第i+1个结点p->next->prior = p->prior;//第原i+1个结点的前驱指向原第i-1个结点free(p);p = NULL;}return 0;}



 

原创粉丝点击