1,引入,数组的分类,静态数组(int arr[20]容易空间溢出或者浪费),动态数组(malloc合理利用空间但是不能快捷的插入或者删除数据,会涉及到大量的数据移动)
链表是一种物理量储存上非连续,按逻辑顺序通过链表中的指针链接,是一种线性储存结构
链表由一系列节点组成(链表中每个元素成为一个节点),节点包括两个部分,数据域和指针域,指针域储存下一个节点的地址
链表的定义,通过结构体实现
1 typedef struct stu
2 {
3 //数据域(自定义)
4 int num;
5 char name[32];
6 float score;
7
8 //指针域 保存下一个节点的地址
9 struct stu *next;
10 }STU;
11
12 void test07()
13 {
14 //链表头
15 STU *head = NULL;
16 //遍历链表
17 STU *pb = NULL;
18 STU data1 = {100,"德玛", 59};
19 STU data2 = {101,"小炮", 89};
20 STU data3 = {102,"小法", 79};
21 STU data4 = {103,"盲僧", 99};
22 STU data5 = {104,"快乐风男", 39};
23
24 head = &data1;
25 data1.next = &data2;
26 data2.next = &data3;
27 data3.next = &data4;
28 data4.next = &data5;
29 data5.next = NULL;
30
31 pb = head;
32 while(pb != NULL)
33 {
34 printf("%d %s %f\n", pb‐>num,pb‐>name,pb‐>score);
35 pb=pb‐>next;//pb指向下一个节点
36 }
37 }
思路,先main中写出程序框架,先调出帮助菜单,接受指令,判断指令调用相应函数,有help,insert,print,search,delete,free,quit
分类 讨论
//链表的尾部插入
2 STU* insert_link(STU *head, STU tmp)
3 {
4 //1、申请待插入的节点
5 STU *pi = (STU *)calloc(1,sizeof(STU));
6 if(pi == NULL)
7 {
8 perror(calloc);
9 return head;
10 }
11
12 //2、将tmp的数据 赋值到 *pi
13 *pi = tmp;
14 pi‐>next = NULL;
15
16 //3、将节点插入到链表的尾部
17 if(head == NULL)//链表不存在
18 {
19 head = pi;
20 return head;
21 }
22 else//链表存在
23 {
24 //a、寻找链表的尾节点
25 STU *pb = head;
26 while(pb‐>next != NULL)//如果不是尾节点
27 pb = pb‐>next;//pb就指向下一个节点
28
29 //b、用尾结点 pb 链接上 插入的节点pi
30 pb‐>next = pi;
31 return head;
32 }
33
34 return head;
35 }
1 //链表的有序插入 以num的顺序为准(小‐‐‐>大)
2 STU* insert_link(STU *head, STU tmp)
3 {
4 //1、给待插入的节点pi 申请 堆区空间
5 STU *pi = (STU *)calloc(1,sizeof(STU));
6 if(pi == NULL)
7 {
8 perror("calloc");
9 return head;
10 }
11
12 //2、将tmp的内容 赋值给 *pi
13 *pi = tmp;
14 pi‐>next = NULL;
15
16 //3、链表节点pi的插入
17 if(head == NULL)//链表不存在
18 {
19 head = pi;
20 return head;
21 }
22 else//存在
23 {
24 //a、寻找插入点
25 STU *pb = head, *pf = head;
26 while(pb‐>num < pi‐>num && pb‐>next != NULL)
27 {
28 pf = pb;
29 pb = pb‐>next;
30 }
31
32 //b、插入点的判断
33 if(pb‐>num >= pi‐>num)//头部 中部插入
34 {
35 if(pb == head)//头部之前插入
36 {
37 pi‐>next = head;
38 head = pi;
39 return head;
40 }
41 else//中部插入
42 {
43 pf‐>next = pi;
44 pi‐>next = pb;
45 return head;
46 }
47 }
48 else//尾部插入
49 {
50 pb‐>next = pi;
51 return head;
52 }
53 }
54 return head;
55 }
1 STU* search_link(STU *head, char *name)
2 {
3 //1、判断链表是否存在
4 if(head == NULL)//不存在
5 {
6 printf("link not found\n");
7 return NULL;
8 }
9 else//链表存在
10 {
11 STU *pb = head;
12
13 //逐个将节点中的name 和 name比较 如果不相等 pb=pb‐>next
14 while(strcmp(pb‐>name,name)!=0 && pb‐>next != NULL)
15 pb = pb‐>next;
16
17 //判断是否找到
18 if(strcmp(pb‐>name,name)==0)//找到
19 return pb;
20 else//没找到
21 return NULL;
22 }
23
24 return NULL;
25 }
1 STU* detele_link(STU *head,char *name)
2 {
3 //1、判断链表是否存在
4 if(head == NULL)//不存在
5 {
6 printf("link not found\n");
7 return head;
8 }
9 else//存在
10 {
11 //2、寻找删除点
12 STU *pf=head, *pb = head;
13 while(strcmp(pb‐>name,name)!=0 && pb‐>next != NULL)
14 {
15 pf = pb;
16 pb = pb‐>next;
17 }
18
19 //3、找到删除点
20 if(strcmp(pb‐>name,name)==0)//找到删除点
21 {
22 //4、判断删除的位置
23 if(pb == head)//删除头结点
24 {
25 head = pb‐>next;
26 free(pb);
27
28 }
29 else//中部 或 尾部节点
30 {
31 pf‐>next = pb‐>next;
32 free(pb);
33 }
34 printf("已成功删除%s的相关节点\n",name);
35 return head;
36 }
37 else//没找到删除点
38 {
39 printf("链表中没有%s相关的数据节点信息\n",name);
40 }
41 }
42 return head;
43 }
1 STU* free_link(STU *head)
2 {
3 //判断链表是否存在
4 if(head == NULL)
5 {
6 printf("link not found\n");
7 return head;
8 }
9 else//链表存在
10 {
11 STU *pb = head;
12
13 //逐个节点释放
14 while(pb != NULL)
15 {
16 //head保存下一个节点的位置
17 head = pb‐>next;
18 //释放pb指向的节点
19 free(pb);
20 //pb 指向 head
21 pb = head;
22 }
23
24 printf("链表已经释放完毕\n");
25 return head;
26 }
27
28 return head;
29 }
链表的插入:头部之前插入 尾部插入 有序插入
1、为插入的节点pi申请空间
2、将tmp的值赋值给*pi *pi = tmp
3、判断链表是否 存在
3-1:不存在 head = pi
3-2: 存在 (尾部插入 有序插入) 寻找插入点 安装具体的位置 插入节点
链表的遍历:
1、判断链表是否存在
1-1:不存在 不执行任何操作
1-2:存在 逐个节点遍历 注意 别越界。
链表的查询:
1、判断链表是否存在
1-1:不存在 不执行任何操作
1-2:存在 逐个节点比较 比较成功返回位置 注意 别越界。
链表节点的删除:
1、判断链表是否存在
1-1:不存在 不执行任何操作
1-2:存在 逐个节点比较 删除指定节点 注意 别越界。
释放链表:
1、判断链表是否存在
1-1:不存在 不执行任何操作
1-2:存在 逐个节点节点释放 注意 别越界
1 STU* reverse_link(STU *head)
2 {
3 //判断链表是否存在
4 if(head == NULL)
5 {
6 printf("link not founf\n");
7 return head;
8 }
9 else//链表存在
10 {
11 //int *p,num;//p为int * , num为int
12 STU *pb,*pr;//pb为STU * , pr为STU *
13
14 //pb保存head‐>next(原因head‐>next会置NULL)
15 pb = head‐>next;
16 //将head‐>next置NULL (原因:头节点变尾节点)
17 head‐>next = NULL;
18
19 while(pb != NULL)
20 {
21 //pr保存pb‐>next (原因:pb‐>next会指向head)
22 pr = pb‐>next;
23
24 //pb‐>next 指向 head (原因:逆转方向)
25 pb‐>next = head;
26
27 //保存 逆转方向的代码 可以重复 执行
28 head = pb;
29 pb = pr;
30 }
31
32 return head;
33 }
34 return head;
35 }
1 #include
2 int main()
3 {
4 int arr[10]={0};
5 int n = sizeof(arr)/sizeof(arr[0]);
6 int i=0,j=0,min=0;
7
8 printf("请输入%d个int数据\n",n);
9 for(i=0;i arr[j])
20 min = j;
21 }
22
23 if(min != i)
24 {
25 int tmp = 0;
26 tmp = arr[i];
27 arr[i]=arr[min];
28 arr[min]=tmp;
29 }
30
31 }
32
33 for(i=0;i
1 void sort_link(STU *head)
2 {
3 //1、判断链表是否存在
4 if(NULL == head)
5 {
6 printf("link not found\n");
7 return;
8 }
9 else
10 {
11 STU *p_i = head;//i=0
12 while(p_i‐>next != NULL)//inext;//j = min+1
16 while(p_j != NULL)//jnum > p_j‐>num)//if(arr[min] > arr[j])
21 p_min = p_j;//min = j
22 p_j = p_j‐>next;//j++
23
24 }
25
26 if(p_min != p_i)//min != i
27 {
28 //只交换数据域(1、节点内容整体交换 2、只交换指针域)
29 //1、节点内容整体交换(数据域交换第1次 指针域交换第1次)
30 STU tmp;
31 tmp = *p_i;
32 *p_i = *p_min;
33 *p_min = tmp;
34
35 //2、只交换指针域(指针域交换第2次)
36 tmp.next = p_i‐>next;
37 p_i‐>next = p_min‐>next;
38 p_min‐>next = tmp.next;
39 }
40
41
42 p_i = p_i‐>next;//i++
43 }
44
45 }
46
47 }
1、布局整个程序框架
main.c
1 #include
2
3 void stu_help(void);
4 int main(int argc,char *argv[])
5 {
6 stu_help();
7
8 while(1)
9 {
10 char cmd[32]="";
11 printf("请输入操作指令:");
12
13 scanf("%s",cmd);
14 if(strcmp(cmd,"help") == 0)
15 {
16 stu_help();
17 }
18 else if(strcmp(cmd,"insert") == 0)
19 {
20 printf("‐‐‐‐‐insert‐‐‐‐‐‐\n");
21 }
22 else if(strcmp(cmd,"print") == 0)
23 {
24 printf("‐‐‐‐‐print‐‐‐‐‐‐\n");
25 }
26 else if(strcmp(cmd,"search") == 0)
27 {
28 printf("‐‐‐‐‐search‐‐‐‐‐‐\n");
29 }
30 else if(strcmp(cmd,"delete") == 0)
31 {
32 printf("‐‐‐‐‐delete‐‐‐‐‐‐\n");
33 }
34 else if(strcmp(cmd,"free") == 0)
35 {
36 printf("‐‐‐‐‐free‐‐‐‐‐‐\n");
37 }
38 else if(strcmp(cmd,"quit") == 0)
39 {
40 break;
41 }
42
43 }
44 return 0;
45 }
46
47 void stu_help(void)
48 {
49 printf("################################\n");
50 printf("#help:打印帮助信息 #\n");
51 printf("#insert:插入链表节点 #\n");
52 printf("#print:遍历链表节点信息 #\n");
53 printf("#search:查询链表节点 #\n");
54 printf("#delete:删除链表节点 #\n");
55 printf("#free:释放链表 #\n");
56 printf("#quit:退出 #\n");
57 printf("################################\n");
58 return;
59 }
2、链表插入节点 之 头部之前插入。
原理分析图:
案例:
main.c
1 #include
2 #include
3 #include "link.h"
4 void stu_help(void);
5 int main(int argc,char *argv[])
6 {
7 //定义一个链表头 注意 一定要赋值为NULL
8 STU *head=NULL;
9
10 stu_help();
11
12 while(1)
13 {
14 char cmd[32]="";
15 printf("请输入操作指令:");
16
17 scanf("%s",cmd);
18 if(strcmp(cmd,"help") == 0)
19 {
20 stu_help();
21 }
22 else if(strcmp(cmd,"insert") == 0)
23 {
24 STU tmp;
25 printf("请输入需要插入的数据:");
26 scanf("%d %s %f",&tmp.num, tmp.name, &tmp.score);
27
28 //将tmp数据 插入到head所指向的链表中
29 head = insert_link(head, tmp);
30 }
31 else if(strcmp(cmd,"print") == 0)
32 {
33 print_link(head);
34 }
35 else if(strcmp(cmd,"search") == 0)
36 {
37 printf("‐‐‐‐‐search‐‐‐‐‐‐\n");
38 }
39 else if(strcmp(cmd,"delete") == 0)
40 {
41 printf("‐‐‐‐‐delete‐‐‐‐‐‐\n");
42 }
43 else if(strcmp(cmd,"free") == 0)
44 {
45 printf("‐‐‐‐‐free‐‐‐‐‐‐\n");
46 }
47 else if(strcmp(cmd,"quit") == 0)
48 {
49 break;
50 }
51
52 }
53 return 0;
54 }
55
56 void stu_help(void)
57 {
58 printf("################################\n");
59 printf("#help:打印帮助信息 #\n");
60 printf("#insert:插入链表节点 #\n");
61 printf("#print:遍历链表节点信息 #\n");
62 printf("#search:查询链表节点 #\n");
63 printf("#delete:删除链表节点 #\n");
64 printf("#free:释放链表 #\n");
65 printf("#quit:退出 #\n");
66 printf("################################\n");
67 return;
68 }
link.c
1 #include
2 #include//calloc
3 #include"link.h"
4 STU* insert_link(STU *head, STU tmp)
5 {
6
7 //1、从堆区申请一个待插入的节点空间
8 STU *pi = (STU *)calloc(1,sizeof(STU));
9 if(pi == NULL)
10 {
11 perror("calloc");
12 return head;
13 }
14
15 //2、将tmp的值 赋值 给*pi
16 *pi = tmp;
17 pi‐>next = NULL;//注意
18
19 //3、将pi插入到链表中
20 if(head == NULL)//链表不存在
21 {
22 head = pi;
23 //return head;
24 }
25 else//链表存在(头部之前插入)
26 {
27 //1、让pi 指向就的头
28 pi‐>next = head;
29
30 //2、head指向新的头节点
31 head = pi;
32
33 //return head;
34 }
35
36 return head;
37 }
38
39 void print_link(STU *head)
40 {
41 if(head == NULL)//链表不存在
42 {
43 printf("link not find\n");
44 return;
45 }
46 else
47 {
48 STU *pb = head;
49 while(pb != NULL)
50 {
51 printf("%d %s %f\n", pb‐>num, pb‐>name,pb‐>score);
52 //pb指向下一个节点
53 pb = pb‐>next;
54 }
55
56 }
57
58 return;
59 }
link.h
1 //防止头文件重复包含
2 #ifndef __LINK_H__
3 #define __LINK_H__
4 //链表节点类型 定义
5 typedef struct stu
6 {
7 //数据域
8 int num;
9 char name[32];
10 float score;
11
12 //指针域
13 struct stu *next;
14 }STU;
15
16 extern STU* insert_link(STU *head, STU tmp);
17 extern void print_link(STU *head);
18 #endif
19
1,设计程序连续接受指令,用个while(1){ },接收键盘输入指令并跳转相应函数,用if else语句条件为(strcmp==0)
2,链表插入之头部插入流程
1,STU temp,先定义一个临时结构体,并获取键盘输入给他赋值
2,从堆区申请一个待插入的节点空间STU *pi = (STU *)calloc(1,sizeof(STU));
3,将temp的值赋给*pi,并注意pi.next=NULL
4,将pi插入到链表中——头部之前插入
1,链表不存在(head==NULL)直接head=pi return
2,链表存在,头部之前插入
1,让pi指向旧的头节点pi->next=head
2,head指向新的头节点,head=pi return head
3,遍历链表,第一步先判断链表是否存在,第二部,STU *pb=head,while(pb!=NULL){printf 然后pb=pb->nextpb指向下一个节点}
认识双向循环链表
双向循环链表插入
1 //头部之前插入
2 STU* insert_link(STU *head, STU tmp)
3 {
4 //1、为插入的节点pi申请空间
5 STU *pi = (STU *)calloc(1,sizeof(STU));
6 //2、将tmp的值 赋值给 *pi
7 *pi = tmp;
8
9 //3、判断链表是否存在
10 if(head == NULL)//链表不存在
11 {
12 head = pi;
13 pi‐>next = head;
14 pi‐>pre = head;
15 }
16 else//链表存在(头部之前插入)
17 {
18 pi‐>next = head;
19 pi‐>pre = head‐>pre;
20 head‐>pre‐>next = pi;
21 head‐>pre = pi;
22 head = pi;
23 }
24
25 return head;
26 }
案例
1 #include
2 #include
3 #include
4 //定义一个双向循环链表的节点类型
5 typedef struct stu
6 {
7 //数据域
8 int num;
9 char name[32];
10 int age;
11
12 //指针域
13 struct stu *next;//指向下一个节点
14 struct stu *pre;//指向前一个节点
15 }STU;
16
17 extern STU* insert_link(STU *head, STU tmp);
18 extern void print_link(STU *head);
19 extern STU* search_link(STU *head, char *name);
20 extern STU* delete_link(STU *head, int num);
21 extern STU* free_link(STU *head);
22
23 int main(int argc,char *argv[])
24 {
25 char name[32]="";
26 int num = 0;
27 int n =0;//保存学生的个数
28 int i=0;
29 STU *head = NULL;
30 STU *ret = NULL;
31
32 printf("请输入学员的个数:");
33 scanf("%d", &n);
34
35 for(i=0;inum, ret‐>name,ret‐>age);
62 }
63 #endif
64 //删除指定节点 num
65 printf("请输入要删除的学号:");
66 scanf("%d", &num);
67 head = delete_link(head, num);
68
69 //遍历整个链表
70 print_link(head);
71
72 //释放整个链表
73 head = free_link(head);
74
75 //遍历整个链表
76 print_link(head);
77
78 return 0;
79 }
80
81 //头部之前插入
82 STU* insert_link(STU *head, STU tmp)
83 {
84 //1、为插入的节点pi申请空间
85 STU *pi = (STU *)calloc(1,sizeof(STU));
86 //2、将tmp的值 赋值给 *pi
87 *pi = tmp;
88
89 //3、判断链表是否存在
90 if(head == NULL)//链表不存在
91 {
92 head = pi;
93 pi‐>next = head;
94 pi‐>pre = head;
95 }
96 else//链表存在(头部之前插入)
97 {
98 pi‐>next = head;
99 pi‐>pre = head‐>pre;
100 head‐>pre‐>next = pi;
101 head‐>pre = pi;
102 head = pi;
103 }
104
105 return head;
106 }
107
108 #if 1
109 void print_link(STU *head)
110 {
111 //判断链表是否存在
112 if(head == NULL)
113 {
114 printf("link not found\n");
115 return;
116 }
117 else//链表存在
118 {
119 STU *pb = head;
120 do
121 {
122 //访问节点内容
123 printf("num=%d, name=%s, age=%d\n", pb‐>num,pb‐>name,pb‐>age);
124 //pb指向下一个节点
125 pb = pb‐>next;
126 }while(pb != head);
127 }
128 return;
129 }
130 #endif
131 #if 0
132 void print_link(STU *head)
133 {
134 //判断链表是否存在
135 if(head == NULL)
136 {
137 printf("link not found\n");
138 }
139 else//链表存在
140 {
141 STU *pb = head;//pb指向头结点
142 STU *pf = head‐>pre;//pf指向了尾节点
143
144 do
145 {
146 if(pb == pf)//相遇 只需要打印pf或pb中任何一个信息就够了
147 {
148 printf("num=%d,name=%s,age=%d\n", pb‐>num,pb‐>name,pb‐>age);
149 break;
150 }
151 printf("num=%d,name=%s,age=%d\n", pb‐>num,pb‐>name,pb‐>age);
152 printf("num=%d,name=%s,age=%d\n", pf‐>num,pf‐>name,pf‐>age);
153
154 pb = pb‐>next;//next方向的移动
155 pf = pf‐>pre;//pre方向的移动
156 }while( pb‐>pre != pf );//pf和pb不能 擦肩而过
157
158 }
159 }
160
161 #endif
162
163 STU* search_link(STU *head, char *name)
164 {
165 //判断链表是否存在
166 if(head == NULL)
167 {
168 return NULL;
169 }
170 else//链表存在
171 {
172 STU *pb = head;//指向头结点
173 STU *pf = head‐>pre;//指向的是尾节点
174 printf("pb = %p\n", pb);
175 printf("pf = %p\n", pf);
176 printf("pb‐>pre = %p\n", pb‐>pre);
177
178
179 while( (strcmp(pb‐>name,name) != 0) && (strcmp(pf‐>name,name)!=0) && (p
b != pf) )
180 {
181 printf("##pb‐>name=%s##\n",pb‐>name);
182 printf("##pf‐>name=%s##\n",pf‐>name);
183 pb=pb‐>next;//next方向移动
184 pf=pf‐>pre;//pf方向移动
185
186 if(pb‐>pre == pf)
187 {
188 break;
189 }
190 }
191
192 if(strcmp(pb‐>name,name) == 0)
193 {
194
195 return pb;
196 }
197 else if(strcmp(pf‐>name,name)==0)
198 {
199 return pf;
200 }
201 }
202
203 return NULL;
204 }
205
206 STU* delete_link(STU *head, int num)
207 {
208 //判断链表是否存在
209 if(head == NULL)
210 {
211 printf("link not found\n");
212 return head;
213 }
214 else
215 {
216 STU *pb = head;//指向头节点
217 STU *pf = head‐>pre;//指向尾节点
218
219 //逐个节点寻找删除点
220 while((pb‐>num != num) && (pf‐>num != num) && (pf != pb))
221 {
222 pb = pb‐>next;//next方向移动
223 pf = pf‐>pre;//pre方向移动
224 if(pb‐>pre == pf)
225 break;
226 }
227
228 if(pb‐>num == num)//删除pb指向的节点
229 {
230
231 if(pb == head)//删除头节点
232 {
233 if(head == head‐>next)
234 {
235 free(pb);
236 head = NULL;
237 }
238 else
239 {
240 head‐>next‐>pre = head‐>pre;
241 head‐>pre‐>next = head‐>next;
242 head = head‐>next;
243 free(pb);
244 }
245
246 }
247 else//删除中尾部节点
248 {
249 pb‐>pre‐>next = pb‐>next;
250 pb‐>next‐>pre = pb‐>pre;
251 free(pb);
252 }
253 }
254 else if(pf‐>num == num)//删除pf指向的节点
255 {
256
257 if(pf == head)//删除头节点
258 {
259 if(head == head‐>next)
260 {
261 free(pf);
262 head = NULL;
263 }
264 else
265 {
266 head‐>next‐>pre = head‐>pre;
267 head‐>pre‐>next = head‐>next;
268 head = head‐>next;
269 free(pf);
270 }
271 }
272 else//删除中尾部节点
273 {
274 pf‐>pre‐>next = pf‐>next;
275 pf‐>next‐>pre = pf‐>pre;
276 free(pf);
277 }
278 }
279 else
280 {
281 printf("未找到%d相关的节点信息",num);
282 }
283 }
284
285 return head;
286 }
287
288 STU* free_link(STU *head)
289 {
290 if(head == NULL)//链表为空
291 {
292 printf("link not found\n");
293 return NULL;
294 }
295 else//链表存在
296 {
297 STU *pb = head;
298 STU *tmp;
299 do
300 {
301 tmp = pb;
302 pb = pb‐>next;
303 free(tmp);
304 }while(pb != head);
305 }
306
307 return NULL;
308 }
链表的遍历
单向遍历
1 void print_link(STU *head)
2 {
3 //判断链表是否存在
4 if(head == NULL)
5 {
6 printf("link not found\n");
7 return;
8 }
9 else//链表存在
10 {
11 STU *pb = head;
12 do
13 {
14 //访问节点内容
15 printf("num=%d, name=%s, age=%d\n", pb‐>num,pb‐>name,pb‐>age);
16 //pb指向下一个节点
17 pb = pb‐>next;
18 }while(pb != head);
19 }
20 return;
21 }
双向遍历
1 void print_link(STU *head)
2 {
3 //判断链表是否存在
4 if(head == NULL)
5 {
6 printf("link not found\n");
7 }
8 else//链表存在
9 {
10 STU *pb = head;//pb指向头结点
11 STU *pf = head‐>pre;//pf指向了尾节点
12
13 do
14 {
15 if(pb == pf)//相遇 只需要打印pf或pb中任何一个信息就够了
16 {
17 printf("num=%d,name=%s,age=%d\n", pb‐>num,pb‐>name,pb‐>age);
18 break;
19 }
20 printf("num=%d,name=%s,age=%d\n", pb‐>num,pb‐>name,pb‐>age);
21 printf("num=%d,name=%s,age=%d\n", pf‐>num,pf‐>name,pf‐>age);
22
23 pb = pb‐>next;//next方向的移动
24 pf = pf‐>pre;//pre方向的移动
25 }while( pb‐>pre != pf );//pf和pb不能 擦肩而过
26
27 }
28 }
双向链表的查找
1 STU* search_link(STU *head, char *name)
2 {
3 //判断链表是否存在
4 if(head == NULL)
5 {
6 return NULL;
7 }
8 else//链表存在
9 {
10 STU *pb = head;//指向头结点
11 STU *pf = head‐>pre;//指向的是尾节点
12 printf("pb = %p\n", pb);
13 printf("pf = %p\n", pf);
14 printf("pb‐>pre = %p\n", pb‐>pre);
15
16
17 while( (strcmp(pb‐>name,name) != 0) && (strcmp(pf‐>name,name)!=0) && (p
b != pf) )
18 {
19 printf("##pb‐>name=%s##\n",pb‐>name);
20 printf("##pf‐>name=%s##\n",pf‐>name);
21 pb=pb‐>next;//next方向移动
22 pf=pf‐>pre;//pf方向移动
23
24 if(pb‐>pre == pf)
25 {
26 break;
27 }
28 }
29
30 if(strcmp(pb‐>name,name) == 0)
31 {
32
33 return pb;
34 }
35 else if(strcmp(pf‐>name,name)==0)
36 {
37 return pf;
38 }
39 }
40
41 return NULL;
42 }
双向链表删除制定节点
1 STU* delete_link(STU *head, int num)
2 {
3 //判断链表是否存在
4 if(head == NULL)
5 {
6 printf("link not found\n");
7 return head;
8 }
9 else
10 {
11 STU *pb = head;//指向头节点
12 STU *pf = head‐>pre;//指向尾节点
13
14 //逐个节点寻找删除点
15 while((pb‐>num != num) && (pf‐>num != num) && (pf != pb))
16 {
17 pb = pb‐>next;//next方向移动
18 pf = pf‐>pre;//pre方向移动
19 if(pb‐>pre == pf)
20 break;
21 }
22
23 if(pb‐>num == num)//删除pb指向的节点
24 {
25
26 if(pb == head)//删除头节点
27 {
28 if(head == head‐>next)//链表只有一个节点
29 {
30 free(pb);
31 head = NULL;
32 }
33 else
34 {
35 head‐>next‐>pre = head‐>pre;
36 head‐>pre‐>next = head‐>next;
37 head = head‐>next;
38 free(pb);
39 }
40
41 }
42 else//删除中尾部节点
43 {
44 pb‐>pre‐>next = pb‐>next;
45 pb‐>next‐>pre = pb‐>pre;
46 free(pb);
47 }
48 }
49 else if(pf‐>num == num)//删除pf指向的节点
50 {
51
52 if(pf == head)//删除头节点
53 {
54 if(head == head‐>next)//链表只有一个节点
55 {
56 free(pf);
57 head = NULL;
58 }
59 else
60 {
61 head‐>next‐>pre = head‐>pre;
62 head‐>pre‐>next = head‐>next;
63 head = head‐>next;
64 free(pf);
65 }
66 }
67 else//删除中尾部节点
68 {
69 pf‐>pre‐>next = pf‐>next;
70 pf‐>next‐>pre = pf‐>pre;
71 free(pf);
72 }
73 }
74 else
75 {
76 printf("未找到%d相关的节点信息",num);
77 }
78 }
79
80 return head;
81 }
释放这个链表节点
1 STU* free_link(STU *head)
2 {
3 if(head == NULL)//链表为空
4 {
5 printf("link not found\n");
6 return NULL;
7 }
8 else//链表存在
9 {
10 STU *pb = head;
11 STU *tmp;
12 do
13 {
14 tmp = pb;
15 pb = pb‐>next;
16 free(tmp);
17 }while(pb != head);
18 }
19
20 return NULL;
21 }