这次就来总结一下链表的六大基础操作:
(1)创建链表
(2)遍历链表
(3)在链表中检索
(4)向链表中插入一项
(5)从链表中删除一项
(6)交换链表中两项的位置
全部都放在一个代码里了,这样好操作一点 /笑哭
至于链表的引申操作,什么头插法尾插法的,都是这六大基础操作之外的事情,有兴趣的话烦请各位自己去了解啦,我这里就不介绍了~
注释都非常详细,我是真的没有啥时间画图做解释了,将就着看吧~
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 const int SIZE = 5;//5个学生信息节点作为测试样例
5 typedef struct student
6 {
7 int number;//学号
8 char name[30];//姓名
9 int score;//成绩
10 struct student* next;//指向下一节点的指针
11 }student;
12
13 student* input(student* stu)//操作①:创建链表
14 {
15 int i;
16 student* p;//将要插入的新节点
17 student* q;//一个引子
18 printf("请输入学生的学号,姓名,成绩(以空格分隔):\n");
19 q = stu;//q初始指向表头
20 for (i = 0; i < SIZE; i++)
21 {
22 p = (student*)malloc(sizeof(student));//为即将插入的信息节点申请空间
23 scanf("%d %s %d", &p->number, p->name, &p->score);
24 p->next = q->next;//保证q->next一定是NULL,排除指向空的情况
25 q->next = p;
26 q = q->next;
27 }
28 return stu;
29 }
30
31 void output(student* stu)//操作②:从头遍历链表(并输出)
32 {
33 student* p = stu->next;
34 while (p != NULL)
35 {
36 printf("%d %s %d\n", p->number, p->name, p->score);
37 p = p->next;
38 }
39 }
40
41 student* check(student* stu)//操作③:在链表中检索某个节点,并带回主函数输出(在这里我以找到第一个成绩为66的学生信息,带回主函数输出为例)
42 {
43 student* p = stu->next;
44 while (p != NULL)
45 {
46 if (p->score == 66)
47 {
48 return p;//找到了返回指针p
49 }
50 else
51 {
52 p = p->next;//否则继续往下找
53 }
54 }
55 return p;
56 }
57
58 student* insert_s(student* stu, student* temp)//操作④:在链表中插入一个节点temp,并带回主函数输出
59 {
60 int flag = 1;//不能写成2,那样会找到第三节点,想想为什么?
61 student* p = stu->next;
62 while (flag)//找到第二节点,并用指针p指向
63 {
64 p = p->next;
65 flag--;
66 }
67 temp->next = p->next;
68 p->next = temp;//注意:此行和上一行不能调换,否则会导致节点丢失!
69 return stu;
70 }
71
72 student* del(student* stu)//操作⑤:删除链表中的某个节点,并带回主函数,输出
73 {
74 int flag = 1;
75 student* p = stu->next;
76 student* q;//q是要删除的那一个节点(在本题中指第三节点)
77 while (flag)//找到第二节点,并用指针p指向
78 {
79 p = p->next;
80 flag--;
81 }
82 q = p->next;
83 q = q->next;
84 free(p->next);//释放节点
85 p->next = q;
86 return stu;
87 }
88
89 student* exchange(student* stu)
90 {
91 int flag1 = 1;//第二节点
92 int flag2 = 4;//第五节点
93 int flag11 = flag1-1;//第二节点前驱节点
94 int flag22 = flag2-1;//第五节点前驱节点
95 student* p = stu->next;//前方节点(在本题中指第二节点)
96 student* q = stu->next;//后方节点(在本题中指第五节点)
97 student* pp = stu->next;//前方节点的前驱节点(在本题中指第一节点)
98 student* qq = stu->next;//后方节点的前驱节点(在本题中指第四节点)
99 student* temp;//中介变量
100 while (flag1)//定位节点p
101 {
102 p = p->next;
103 flag1--;
104 }
105 while (flag2)//定位节点q
106 {
107 q = q->next;
108 flag2--;
109 }
110 while (flag11)//定位节点pp
111 {
112 pp = pp->next;
113 flag11--;
114 }
115 while (flag22)//定位节点qq
116 {
117 qq = qq->next;
118 flag22--;
119 }
120 /*=================*///交换p->next和q->next
121 temp = p->next;
122 p->next = q->next;
123 q->next = temp;
124 /*=================*///交换pp->next和qq->next
125 pp->next = q;
126 qq->next = p;
127 /*=================*///交换p和q
128 p = pp->next;
129 q = qq->next;
130 /*=================*/
131 return stu;
132 }
133
134 int main()
135 {
136 student* stu;//定义表头指针
137 student* s;//中介指针1
138 student* ss;//中介指针2
139 student* temp;
140 /*======================================================*///建立表头
141 stu = (student*)malloc(sizeof(student));//为表头节点分配空间
142 stu->next = NULL;
143 /*======================================================*/
144 //操作①:建立单链表,并用s指向
145 s = input(stu);
146
147 //操作②:输出这个链表
148 printf("\n");
149 output(s);
150
151 //操作③:在链表中检索某个节点,并用s指向
152 ss = check(s);
153 printf("\n%d %s %d\n", ss->number, ss->name, ss->score);//输出特定节点的所有信息
154
155 //操作④:在建立好的链表第二三节点间插入节点temp,并输出检验
156 temp = (student*)malloc(sizeof(student));
157 scanf("%d %s %d", &temp->number, temp->name, &temp->score);
158 ss = insert_s(s, temp);
159 printf("\n");
160 output(ss);
161
162 //操作⑤:删除已经建立好的链表中的第三节点,并输出检验
163 ss = del(s);
164 printf("\n");
165 output(ss);
166
167 //操作⑥:交换建立好的链表中的第二和第五节点,并输出检验
168 ss = exchange(s);
169 printf("\n");
170 output(ss);
171 return 0;
172 }