码迷,mamicode.com
首页 > 其他好文 > 详细

双向链表

时间:2014-10-15 14:13:10      阅读:271      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   color   io   ar   for   sp   数据   

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <malloc.h>
  4 #include <stdlib.h>
  5 
  6 #define OVERFLOW 0
  7 #define TRUE true
  8 #define FALSE false
  9 #define OK 1
 10 #define ERROR 0
 11 
 12 typedef int ElemType;
 13 typedef bool Status;
 14 
 15 
 16 typedef struct DuLNode{
 17     //定义自己的数据类型
 18     ElemType data;
 19     struct DuLNode *prior, *next;
 20 }DuLNode, *DuLinkList;
 21 
 22 //带头节点的双向循环链表的基本操作
 23 void InitList(DuLinkList *L){
 24     //产生空的双向循环链表
 25     *L = (DuLinkList)malloc(sizeof(DuLNode));
 26     if(*L){
 27         (*L)->next = (*L)->prior = *L;
 28     }
 29     else{
 30         exit(OVERFLOW);
 31     }
 32 }
 33 
 34 //销毁循环链表L
 35 void DestroyList(DuLinkList *L){
 36     DuLinkList q, p = (*L)->next; //p指向第一个结点
 37     while(p != *L){
 38         q = p->next;
 39         free(p);
 40         p = q;
 41     }
 42     free(*L);
 43     *L = NULL;
 44 }
 45 
 46 //重置链表为空表
 47 void ClearList(DuLinkList L){//不改变L
 48     DuLinkList q, p = L->next; //p指向第一个结点
 49     while(p != L){//p没到表头
 50         q = p->next;
 51         free(p);
 52         p = q;
 53     }
 54     L->next = L->prior = L; //头结点的两个指针域均指向自身
 55 }
 56 
 57 //验证是否为空表
 58 Status ListEmpty(DuLinkList L){
 59     //初始条件:线性表L已存在
 60     if(L->next == L && L->prior == L){
 61         return TRUE;
 62     }
 63     else{
 64         return FALSE;
 65     }
 66 }
 67 
 68 //计算表内元素个数
 69 int ListLength(DuLinkList L){
 70     //初始条件:L已存在
 71     int i = 0;
 72     DuLinkList p = L->next; //p指向第一个结点
 73     while(p != L){ //p没到表头
 74         i++;
 75         p = p->next;
 76     }
 77     return i;
 78 }
 79 
 80 //赋值
 81 Status GetElem(DuLinkList L, int i, ElemType *e){
 82     //当第i个元素存在时,其赋值给e并返回OK,否则返回ERROR
 83     int j = 1//j为计数器
 84     DuLinkList p = L->next; //p指向第一个结点
 85     while(p != L && p->next){
 86         j++;
 87     }
 88     if(p == L || j < i){//第i个元素不存在
 89         return ERROR;
 90     }
 91     *e = p->data; //取第i个元素
 92     return OK;
 93 }
 94 
 95 Status compare(ElemType e1, ElemType e2){
 96     if(e1 == e2){
 97         return TRUE;
 98     }
 99     else{
100         return FALSE;
101     }
102 }
103 
104 //查找元素
105 int LocateElem(DuLinkList L, ElemType e, Status(*cmppare)(ElemType, ElemType)){
106     //初始条件:L已存在, compare是数据元素判定函数
107     //操作结果:返回L中第一个与e满足关系compare()的数据元素位序
108     //若这样的数据元素不存在,则返回值为0
109     int i = 0;
110     DuLinkList p = L->next;  //p指向第一个元素
111     while(p != L){
112         i++;
113         if(compare(p->data, e)){//找到这样的数据元素
114             return i;
115         }
116         p = p->next;
117     }
118     return 0;
119 }
120 
121 
122 //查找元素前驱
123 Status PriorElem(DuLinkList L, ElemType cur_e, ElemType *pre_e){
124     //操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱
125     //否则操作失败,pre_e无定义
126     DuLinkList p = L->next->next;  //p指向第二个元素
127     while(p != L){ //p没到表头
128         if(p->data == cur_e){
129             *pre_e = p->prior->data;
130             return TRUE;
131         }
132         p = p->next;
133     }
134     return FALSE;
135 }
136 
137 //查找后继元素
138 Status NextElem(DuLinkList L, ElemType cur_e, ElemType *next_e){
139     //操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回她的后继
140     //否则操作失败,next_e无定义
141     DuLinkList p = L->next->next; //p指向第二个元素
142     while(p != L){
143         if(p->prior->data == cur_e){
144             *next_e = p->data;
145             return TRUE;
146         }
147         p = p->next;
148     }
149     return FALSE;
150 }
151 
152 //查找元素地址
153 DuLinkList GetElemP(DuLinkList L, int i){//另加
154     //在双向链表L中返回第i个元素的地址,i为0,则返回头结点的地址,若第i个元素不存在,则返回NULL
155     int j;
156     DuLinkList p = L; //p指向头结点
157     if(i < 0 || ListLength(L)) {//i值不合法
158         return NULL;
159     }
160     for(j = 1; j <= i; j++){
161         p = p->next;
162     }
163     return p;
164 }
165 
166 //元素的插入
167 Status lisInsert(DuLinkList L, int i, ElemType e){
168     //在带头结点的双向循环链表L中的第i个位置之前插入元素e,i的合法值为1<= i <= 表长 + 1
169     //改进算法2.18,否则无法在第表长+1个节点之前插入元素
170     DuLinkList p, s;
171     if(i < 1 || i > ListLength(L) + 1){ //i值不合法
172         return ERROR;
173     }
174     p = GetElemP(L, i - 1);//在L中确定第i个元素的前驱的位置指针p
175     if(!p){ //p = NULL,即第i个元素的前驱不存在(设头结点为第1个元素的前驱)
176         return ERROR;
177     }
178     s = (DuLinkList)malloc(sizeof(DuLNode));
179     if(!s){
180         return OVERFLOW;
181     }
182     s->data = e;
183     s->prior = p;  //在第i-1个元素之后插入
184     s->next = p->next;
185     p->next->prior = s;
186     p->next = s;
187     return OK;
188 }
189 
190 //元素的删除
191 Status ListDelete(DuLinkList L, int i, ElemType *e){
192     //删除带头结点的双向循环链表L的第i个元素,i的合法值为1<= i <= 表长
193     DuLinkList p;
194     if(i < 1){//i值不合法
195         return ERROR;
196     }
197     p = GetElemP(L, i);//在L中确定第i个元素的位置指针p
198     if(!p){//p=NULL,即第i个元素不存在
199         return ERROR;
200     }
201     *e = p->data;
202     p->prior->next = p->next;
203     p->next->prior = p->prior;
204     free(p);
205     return OK;
206 }
207 
208 void *visit(ElemType e){
209     //TODO
210 }
211 //正序查找
212 void ListTraverse(DuLinkList L, void(*vist)(ElemType)){
213     //由双链循环线性表L的头结点出发,正序对每个元素调用函数visit()
214     DuLinkList p = L->next;//p指向头结点
215     while(p != L){
216         visit(p->data);
217         p = p->next;
218     }
219     printf("\n");
220 }
221 
222 //逆序查找
223 void ListTraverseBack(DuLinkList L, void(*visit)(ElemType)){
224     //由双链循环线性表L的头结点出发,逆序对每个元素调用函数visit(),另加
225     DuLinkList p = L->prior;//p指向头结点
226     while(p != L){
227         visit(p->data);
228         p = p->prior;
229     }
230     printf("\n");
231 }
232 
233 int main(){
234     return 0;
235 }

双向链表

标签:des   style   blog   color   io   ar   for   sp   数据   

原文地址:http://www.cnblogs.com/angle-qqs/p/4026130.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!