为了得到一个简洁的C语言实现的双向链表,本篇参照数据结构书籍对双向链表的做了一些修改,内容有:
1.合并分离的头文件和实现文件,认识更为直观;
2.修改函数名和变量名,更贴近自身的理解;
3.删除了返回首节点、尾节点等功能更为单一的函数,留下其主干。
实现思路:
1.定义一个双向链表
2.进行初始化工作:调用initList(),构造一个空的双向链表
3.执行增删改查等操作(节点操作)
*插入时注意:封装成节点
1 /*双向链表实现代码*/
2 #include<malloc.h>
3 #include<stdlib.h>
4 #include<stdio.h>
5
6 typedef struct ListNode * PNode;
7 /*定义列表节点类型*/
8 typedef struct ListNode
9 {
10 int data; /*数值*/
11 PNode pred; /*前驱*/ //struct ListNode* pred;(可以)
12 PNode succ; /*后继*/ //ListNode* pred;(不可以)
13 }ListNode;
14 /*定义链表类型*/
15 typedef struct List
16 {
17 int size; /*规模*/
18 PNode header; /*头哨兵*/
19 PNode trailer; /*尾哨兵*/
20 }List;
21
22 /*构造值为i的节点,并返回节点地址*/
23 PNode makeNode(int i);
24
25 /*初始化:构造一个空的双向链表*/
26 List* initList();
27
28 /*摧毁一个双向链表*/
29 void destroyList(List *plist);
30
31 /*将一个链表置为空表,释放原链表节点空间*/
32 void clearList(List *plist);
33
34 /*将pnode作为首节点插入*/
35 PNode insertAsFirst(List *plist,PNode pnode);
36
37 /*将链表首节点节点删除,并返回其地址*/
38 PNode deleteFirst(List *plist);
39
40 /*删除链表中的末节点并返回其地址*/
41 PNode listRemove(List *plist);
42
43 /*在链表中p位置之前插入新节点S*/
44 PNode insertBefore(List *plist,PNode p,PNode s);
45
46 /*在链表中p位置之后插入新节点s*/
47 PNode insertAfter(List *plist,PNode p,PNode s);
48
49 /*返回在链表中第i个节点的位置*/
50 PNode locatePos(List *plist,int i);
51
52 /*遍历列表中元素:调用函数visit()*/
53 void listTraverse(List *plist,void (*visit)());
54
55 /*构造值为i的节点,并返回节点地址*/
56 PNode makeNode(int i)
57 {
58 PNode p = (PNode)malloc(sizeof(ListNode));
59 p->data = i;
60 p->pred = NULL;
61 p->succ = NULL;
62
63 return p;
64 }
65
66 /*初始化:构造一个空的双向链表*/
67 List * initList()
68 {
69 List *plist = (List *)malloc(sizeof(List));
70 plist->header = makeNode(0);//创建头哨兵节点
71 plist->trailer = makeNode(0);//创建尾哨兵节点
72 plist->header->succ = plist->trailer;
73 plist->trailer->pred = plist->header;
74
75 plist->size = 0;//记录规模
76 return plist;
77 }
78
79 /*摧毁一个双向链表*/
80 void destroyList(List *plist)
81 {
82 //释放节点
83 clearList(plist); //先将一个列表置为空表,即释放表内节点
84 free(plist->header); free(plist->trailer);//再释放头尾哨兵节点
85 //释放链表
86 free(plist);
87 }
88
89 /*判断链表是否为空表*/
90 int isEmpty(List *plist)
91 {
92 if((plist->size==0) || plist->header->succ == plist->trailer)
93 return 1;
94 else
95 return 0;
96 }
97
98 /*将一个链表置为空表,释放原链表节点空间*/
99 void clearList(List *plist)
100 {
101 PNode temp;
102 while(!isEmpty(plist))
103 {
104 PNode p=plist->header->succ;
105 temp = p->succ;
106 free(p);
107 plist->header->succ = temp;
108 plist->size--;
109 }
110 }
111
112 /*将pnode作为首节点插入,返回该节点的地址*/
113 PNode insertAsFirst(List *plist,PNode pnode)
114 {
115 PNode temp = plist->header->succ;//暂存header的后继结点
116
117 temp->pred=pnode; plist->header->succ = pnode;
118 pnode->pred = plist->header; pnode->succ=temp;
119
120 plist->size++;
121 return pnode;
122 }
123
124 /*将链表第一个节点删除,返回该节点的地址*/
125 PNode deleteFirst(List *plist)
126 {
127 PNode p=plist->header->succ;
128
129 p->succ->pred = p->pred;
130 p->pred->succ = p->succ;
131
132 plist->size--;
133 return p;
134 }
135
136 /*删除链表中的末节点,并返回该节点地址*/
137 PNode listRemove(List *plist)
138 {
139 PNode p=plist->trailer->pred;
140
141 p->succ->pred = p->pred;
142 p->pred->succ = p->succ;
143
144 plist->size--;
145 return p; //在main中释放
146 }
147
148 /*在链表中p位置之前插入新节点s*/
149 PNode insertBefore(List *plist,PNode p,PNode s)
150 {
151 s->pred = p->pred; s->succ = p;
152 p->pred->succ = s; p->pred = s;
153
154 plist->size++;
155 return s;
156 }
157
158 /*在链表中p位置之后插入新节点s*/
159 PNode insertAfter(List *plist,PNode p,PNode s)
160 {
161 s->succ = p->succ; s->pred = p;
162 p->succ->pred = s; p->succ = s;
163
164 plist->size++;
165 return s;
166 }
167
168 /*返回在链表中第i个节点的位置*/
169 PNode locatePos(List *plist,int i)
170 {
171 int cnt = 0;
172 PNode p = plist->header;
173 if(i>(plist->size)||i<1)
174 return NULL;
175
176 while(++cnt<=i)
177 {
178 p=p->succ;
179 }
180
181 return p;
182 }
183
184 /*遍历列表中元素:调用函数visit()*/
185 void listTraverse(List *plist,void (*visit)())
186 {
187 PNode p = plist->header;
188 if(isEmpty(plist))
189 return;
190 else
191 {
192 while(p->succ != plist->trailer)
193 {
194 p = p->succ;
195 visit(p->data);
196 }
197 }
198 }
199
200
201 void print(int i)
202 {
203 printf("数据项为%d \n",i);
204 }
205 main()
206 {
207 List *plist = NULL;
208 PNode p = NULL;
209
210 plist = initList();
211 p = insertAsFirst(plist,makeNode(1));
212 insertBefore(plist,p,makeNode(2));
213 insertAfter(plist,p,makeNode(3));
214
215 printf("p前驱位置的值为%d\n",p->pred->data);
216 printf("p位置的值为%d\n",p->data);
217 printf("p后继位置的值为%d\n",p->succ->data);
218
219
220 printf("遍历输出各节点数据项:\n");
221 listTraverse(plist,print);
222 printf("除了头节点该链表共有%d个节点\n",plist->size);
223 free(deleteFirst(plist));
224 printf("删除第一个节点后重新遍历输出为:\n");
225 listTraverse(plist,print);
226 printf("除了头节点该链表共有%d个节点\n",plist->size);
227 destroyList(plist);
228 printf("链表已被销毁\n");
229 }
时间: 2024-08-06 20:07:34