0%

线性链表的 C 语言实现

无聊来水一水博客,代码内容如题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct LNode
{
int data; // 数据域
LNode* next; // 指针域(指向结点的指针)
};

LNode* head; // 全局定义链表头指针

void init_ListHead() // 初始化链表头指针
{
head = (LNode*)malloc(sizeof(LNode));
head->data = 0;
head->next = NULL;
}

void init_List() // 初始化单链表
{
int data;
int length;
LNode* last = (LNode*)malloc(sizeof(LNode));
printf("please initialize a list\n");
printf("The length of your list: ");
scanf("%d", &length);
while (head->data < length && scanf("%d", &data) == 1) {
LNode* Node = (LNode*)malloc(sizeof(LNode));
if(head->data == 0) head->next = Node; // 初始化 head 指针
last->next = Node; // 将 Node 设为 last 的后继
Node->data = data; // 初始化 Node 结点
Node->next = NULL;
last = Node; // last 指针后移
head->data++;
}
}

void prt_List()
{
LNode* p = head->next;
for ( ; p != NULL; p = p->next) // 顺序遍历
printf("\t%d", p->data);
printf("\n");
}

int getElem_List(int i)
{
int element;
LNode* p = head->next; int j = 1;
while (p && j < i) { // 顺指针向后查找
p = p->next; ++j;
}
if (!p || j > i) { // 第 i 个元素不存在
printf("ERROR!\n");
return -1;
}
element = p->data; // 取第 i 个元素
return element;
}

void insert_List(int i, int element)
{
int j = 0;
LNode* p = (LNode*)malloc(sizeof(LNode));
p = head;
while (p && j < i - 1) { // 寻找第 i-1 个结点
p = p->next; ++j;
}
if (!p || j > i - 1) { // i 小于 1 或者大于表长+1
printf("ERROR!\n");
return;
}
LNode* newNode = (LNode*)malloc(sizeof(LNode)); // 生成新结点
newNode->data = element; // 插入 L 中
newNode->next = p->next;
p->next = newNode;
head->data++;
return;
}

void remove_List(int i)
{
int j = 0;
LNode* p = (LNode*)malloc(sizeof(LNode));
p = head;
while (p->next && j < i - 1) { // 寻找第 i 个结点,并令 p 指向其前驱
p = p->next; ++j;
}
if (!(p->next) || j > i - 1) { // 删除位置不合理
printf("ERROR!\n");
return;
}
LNode* q = (LNode*)malloc(sizeof(LNode));
q = p->next; // 删除并释放结点
p->next = q->next;
free(q);
head->data--;
return;
}

void clear_List()
{
while (head->next) {
LNode* p = (LNode*)malloc(sizeof(LNode));
p = head->next;
head->next = p->next;
free(p);
}
head->data = 0;
}

void putElem_List(int i, int element)
{
int j = 0;
LNode* p = (LNode*)malloc(sizeof(LNode));
p = head;
while (p && j < i) {
p = p->next; ++j;
}
if (!p || j > i) { // 第 i 个元素不存在
printf("ERROR!\n");
return;
}
p->data = element;
return;
}

void rec_inv_prt_List(LNode* p)
{
if (p->next != NULL) {
rec_inv_prt_List(p->next);
}
printf("\t%d", p->data);
}

void inv_prt_List()
{
LNode* p = head->next;
if(p != NULL) rec_inv_prt_List(p);
printf("\n");
}

int main() {

/***** 函数声明 *****/
void init_ListHead();
void init_List();
void prt_List();
int getElem_List(int i);
void insert_List(int i, int element);
void remove_List(int i);
void clear_List();
void putElem_List(int i, int element);
void rec_inv_prt_List(LNode * p);
void inv_prt_List();

/***** 参数初始化 *****/
int x, i;
int value;
char mode[20];
int index = -1;
char flag;

/***** 初始化线性链表头指针 *****/
init_ListHead();

/***** 初始化线性链表 *****/
init_List();

while (1) {
printf("Please choose a mode:\n");
scanf("%s", &mode);
if (strcmp(mode, "get") == 0) index = 1;
else if (strcmp(mode, "len") == 0) index = 2;
else if (strcmp(mode, "ins") == 0) index = 3;
else if (strcmp(mode, "rem") == 0) index = 4;
else if (strcmp(mode, "clr") == 0) index = 5;
else if (strcmp(mode, "put") == 0) index = 6;
else if (strcmp(mode, "pnt") == 0) index = 7;
else if (strcmp(mode, "rev") == 0) index = 8;
else if (strcmp(mode, "help") == 0) index = 9;
else if (strcmp(mode, "quit") == 0) index = 0;
else {
printf("Wrong command!\n");
printf("You could type in the command \"help\"\n");
index = -1;
continue;
}
switch (index)
{
case 0:
/***** 退出 *****/
exit(0);
case 1:
/***** 返回第 i 个数据元素的值 *****/
printf("get element at node i:\n");
scanf("%d", &i);
value = getElem_List(i);
if(value != -1) printf("%d\n", value);
break;
case 2:
/***** 求线性链表的表长 *****/
printf("length: %d\n", head->data);
break;
case 3:
/***** 在第i个节点处插入数据元素x *****/
printf("insert element x at node i: (type in i first)\n");
scanf("%d%d", &i, &x);
insert_List(i, x);
prt_List();
break;
case 4:
/***** 删除第i个节点 *****/
printf("remove element at node i:\n");
scanf("%d", &i);
remove_List(i);
prt_List();
break;
case 5:
/***** 将单链表重置为一个空表 *****/
clear_List();
printf("Recreate the list? [Y/N](default N): ");
getchar();
scanf("%c", &flag);
if (flag == 'Y') init_List();
break;
case 6:
/***** 改变第i个数据元素的值 *****/
printf("change the value of node i to x: (type in i first)\n");
scanf("%d%d", &i, &x);
putElem_List(i, x);
prt_List();
break;
case 7:
/***** 显示链表中的数据元素 *****/
printf("Output:");
prt_List();
break;
case 8:
/***** 逆序显示链表中的数据元素 *****/
printf("Reverse output:");
inv_prt_List();
break;
case 9:
/***** 帮助 *****/
printf("You could enter \"get\", \"len\", \"ins\", \"rem\", \"put\", \"clr\", \"pnt\" or \"rev\" to choose a mode or enter \"quit\" to end the program\n");
break;
default:
break;
}
}
return 0;
}