C语言链表的实现

本文实现了数据结构中链表的c语言表达,本且尝试创建一个完整文件而非单一的.c文件。使用的IDE是VS2019,作为c语言的初学者,许多地方做的不够完善还请海涵。在代码过程中遇到的问题与解答已附在代码中。

1.文件之间的“沟通”

设置main.c文件作为主文件,single dir.c存放链表的各种函数,head.h是头文件。在main文件中要在开头调用head文件。格式:#include”head.h”。在head文件里主要存放定义好的结构体,函数声明。在存放函数的single dir文件中也要开头调用head文件。

2.代码部分

所有函数只接受头指针。

结构体定义:

1
2
3
4
5
6
7
8
9
10
11
typedef struct {
char name[20];
int price;
int order;
}BookInf;


typedef struct node{
BookInf Book;
struct node* next;
}Node;

主函数部分:通过useall函数(位于single dir文件)作为一个接口,执行功能函数内容在useall里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"head.h"


int main() {
Node* SDHead = (Node*)malloc(sizeof(Node));
if (SDHead)
{
UseAll_SD(SDHead);
}
return 0;
}

功能函数部分(写代码过程中的问题已经放到注释里面了):

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
#include"head.h"
#include<string.h>
#include<stdlib.h>
#include<stdio.h>

static int n; //This n is to record times Add() is called so as to pass the order to p->Book.order.


void Initialize(Node* head) //If you want to keep this function running in main.c, use extern for its return object
{ //The function Initalize change the value of the pointer
strcpy_s(head->Book.name, 20, " ");
head->Book.price = 0; //Node head's data is empty.
head->Book.order = 0;
head->next = NULL;
}


void Add(Node* head)
{
char receive_name[20];
int receive_price;
Node* last = head;
Node* p = (Node*)malloc(sizeof(Node));
int i;
if (last && p) {
p->Book.order = 1;
printf("Please input the book name:\n");
gets_s(receive_name, 20);
setvbuf(stdin, NULL, _IOFBF, 512); //setvbuf is a function that clears the buffers.
printf("Please input the price of te book:\n");
scanf_s("%d", &receive_price);
setvbuf(stdin, NULL, _IOFBF, 512);
n += p->Book.order;
p->Book.order = n;
for (i = 0; i <= 19; i++) {
p->Book.name[i] = receive_name[i]; //Both Book.name and receive_name are strings defined by arrays, use for loop to copy.
}
p->Book.price = receive_price;
p->next = NULL;
if (last) { //At the beginning, last points to head. Head's next area is NULL.
while (last->next) {
last = last->next; //To find the real last one.
}
last->next = p;
}
else {
head->next = p;
}
printf("The last book is: %s\n", p->Book.name);
printf("The price of the book is: %d\n", p->Book.price);
printf("The order of the book is: %d\n", p->Book.order);
}
}


void ShowList(Node* head)
{
Node* pointer1 = head->next;
do
{
if (pointer1) {
printf("Current information:\n");
printf("Book name: %s Price: %d Order: %d\n", pointer1->Book.name, pointer1->Book.price, pointer1->Book.order);
pointer1 = pointer1->next;
}
else
{
printf("ERROR!");
}
} while (pointer1);
}


void ListEmpty(Node* head)
{
if (head->next)
{
printf("The list is not empty.\n");
}
else
{
printf("The list is empty.\n");
}
}


void DestoryList(Node* head)
{
Node* p;
while (head)
{
p = head;
head = head->next;
free(p);
}
printf("The linked list is destoryed./n");
}


void ClearList(Node* head)
{
Node* p, * q;
p = head->next;
while (p)
{
q = p->next;
free(p);
p = q;
}
printf("The linked list is cleared./n");
head->next = NULL;
}


void ListLength(void)
{
printf("The current length is %d\n", n);
}


void GetElem(Node* head)
{
int i, j = 0;
Node* p = head;
printf("Input the position you want to search:\n");
scanf_s("%d", &i);
do
{
p = p->next;
j++;
}while (i != j && p);
if (p)
{
printf("The book at position %d is %s\n", i, p->Book.name);
printf("The price is %d\n", p->Book.price);
}
}


void LocateElem(Node* head)
{
Node* p = head;
char r_name[20];
int i = 0;
printf("Input the book name:\n");
gets_s(r_name, 20);
while (p)
{
if (strcmp(p->Book.name, r_name) == 0)
{
printf("The book you are searching for is at the position %d\n", i);
break;
}
if (p->next == NULL && strcmp(p->Book.name, r_name) != 0)
{
printf("Book %s is not found.", r_name);
}
i++;
p = p->next;
}
}


void Insert(Node* head)
{
int i, j, k = 1;
int l = 0;
char r_name[20];
Node* p = head;
Node* new = (Node*)malloc(sizeof(Node));
if (new)
{
printf("Input the position you want to insert:\n");
scanf_s("%d", &i);
setvbuf(stdin, NULL, _IOFBF, 512);
printf("Input book name:\n");
gets_s(r_name, 20);
setvbuf(stdin, NULL, _IOFBF, 512);
printf("Input the price of the book:\n");
scanf_s("%d", &j);
setvbuf(stdin, NULL, _IOFBF, 512);
for (l = 0; l <= 19; l++)
{
new->Book.name[l] = r_name[l];
}
new->Book.order = i;
new->Book.price = j;
while (p && k < i) // Find the position i - 1
{
p = p->next;
k++;
}
if (p)
{
new->next = p->next;
p->next = new; //Q1: Why this line changes the content of linked list.
p = p->next->next; //Q1: Why this line changes the content of linked list.
}

while (p)
{
p->Book.order++;
p = p->next;
}
}
}


void ElemDelete(Node* head)
{
Node* p = head;
Node* q;
int i, j = 0;
printf("Input the posiotion you want to delete:");
scanf_s("%d", &i);
do
{
p = p->next;
j++;
} while ((i - 1) != j && p);
if (p)
{
q = p->next;
p->next = q->next;
p->next->Book.order -= 1;
free(q);
}
}


void UseAll_SD(Node* head)
{
Initialize(head);
Add(head);
Add(head);
Add(head);
ShowList(head);
Insert(head);
ShowList(head);
ElemDelete(head);
ShowList(head);
GetElem(head);
ClearList(head);
ShowList(head);
}

头文件:

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
#ifndef _Initialize_H_
#ifndef _Add_H_
#define _Initialize_H_
#define _Add_H_


typedef struct {
char name[20];
int price;
int order;
}BookInf;


typedef struct node{
BookInf Book;
struct node* next;
}Node;



void Initialize(Node* head);
void Add(Node* head);
void ShowList(Node* head);
void ListEmpty(Node* head);
void DestoryList(Node* head);
void ClearList(Node* head);
void ListLength(head);
void GetElem(Node* head);
void LocateElem(Node* head);
void Insert(Node* head);
void ElemDelete(Node* head);
void UseAll_SD(Node* head);
#endif
#endif

3.反思与改进

1.对于extern的使用方法不明确,一开始以为必须加,但是发现不加也没什么影响。

2.对于初始化函数的执行很模糊。经提问得知main函数里必须直接分配空间,局部变量才在内部分配。一般的数据结构不需要人为分配,比如整数,但是像结构体指针这样的就需要。

查看评论