线性表基础函数C语言实现

本dome的变量为elemType,可以通过.h文件中更改

Talk is cheap;

show you the code;

ListAPI.h

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

//初始分配量
#define LIST_SIZE 100

//分配增量
#define LIST_INCREMENT 10

#define ERROR -1

typedef int elemType;

typedef int Status;

//定义静态顺序表
//用‘.’访问变量
typedef struct {

elemType elem[LIST_SIZE];
int length;

}SqList;

//定义动态顺序表
//用‘->’访问变量
typedef struct {

elemType *elem; //存储空间基地址
int length;
int listsize;

}MutableSqList;

//结点和单链表的定义
typedef struct LNode{

elemType data; //数据域
struct LNode *next; //指针域

}LNode, *LinkList;

//双向链表的定义
typedef struct DulNode{

elemType data; //数据域
struct DulNode *prior; //指向前驱的指针
struct DulNode *next; //指向后继的指针

}DulNode, *DulLinkList;

//初始化动态顺序表
int initList(MutableSqList *L);

//在顺序表中查找某元素,若没有返回-1,若有则返回当前下标
int locateElem(SqList L, elemType x);

//顺序表插入元素
Status listInsert_musq(MutableSqList *L, int i, elemType e);

//顺序表删除某个元素,并将其返回
Status listDelete(MutableSqList *L, int i, elemType *e);

//初始化单链表
LinkList initLinkList(LNode *L);

//遍历单链表
int printLinkList(LNode *L);

//单链表中取第i个数据
Status getElem(LNode *L, int i, elemType *e);

//单链表中插入数据元素
Status listInsert_ln(LNode *L, int i, elemType e);

//在单链表中删除某一元素
Status listDelete_ln(LNode *L, int i, elemType *e);

//重置为新表
Status listClear_ln(LNode *L);

//求链表长度
int lengthLinkList(LNode *L);

//构造单链表的两个方法:头插法和尾插法。其中尾插法又分为无头结点以及带头结点
//头插法
LinkList listCreate_ln_front(LNode *L);

//尾插法--无头结点
LinkList listCreate_ln_latter_no(LNode *L);

//尾插法--带头结点
LinkList listCreate_ln_latter_yes(LNode *L);

ListAPI.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
256
257
258
259
260
261
262
263
264
#include "ListAPI.h"

int initList(MutableSqList *L) {

L -> elem = (int *)malloc(LIST_SIZE * sizeof(int));

if (!L -> elem) {
return ERROR;
}

L -> length = 0;
L -> listsize = LIST_SIZE;

return 0;
}

int locateElem(SqList L, elemType x) {

int i = 0;

while (i <= L.length && L.elem[i] != x) {
i++;
}

if (i > L.length) {
return ERROR;
} else
return i;

}

Status listInsert_musq(MutableSqList *L, int i, elemType e) {
//在线性表第i个位置插入新元素e

//检查插入位置是否合法
if (i < 1 || i > L ->length) {
return ERROR;
}

elemType *q = &L -> elem[i - 1];
elemType *p = &L -> elem[L -> length - 1];

//元素右移
for (; p >= q; --p) {
*(p + 1) = *p;
}

*q = e;
++L -> length;//表长加一

if (L -> length > L -> listsize) {
return ERROR;
}

return 1;
}

Status listDelete(MutableSqList *L, int i, elemType *e) {

if (i < 1 || i > L -> length) {
return ERROR;
}

elemType *p = &L -> elem[i - 1];
e = p;
elemType *q = &L -> elem[L -> length - 1];

for (++p; p <= q; --q) {
*(p - 1) = *p;
}

--L -> length;

return *e;
}

LinkList initLinkList(LNode *L) {

L = (LNode *)malloc(sizeof(LNode));
if (!L) {
printf("Error");
}
(L) -> next = NULL;
return L;
}

Status getElem(LNode *L, int i, elemType *e){
//L是带头结点链表的头指针,e为取得的元素

LNode *p = L -> next;
int j = 1;//计数器

while (p && j < i) {
p = p -> next;
++j;
}

if (!p || j > i) {
return ERROR;
}

e = &p -> data;

return *e;
}

Status listInsert_ln(LNode *L, int i, elemType e) {
//L是带头结点链表的头指针,在第i个结点之前插入新的元素
//此算法为后插结点

LNode *p = L;
int j = 0;

while (p && j < i) {
p = p -> next;
++j;
}

if (!p || j > i) {
return ERROR;
}

//建立新的结点
LNode *s = (LNode *)malloc(sizeof(LNode));
if (!s) {
return ERROR;
}
s -> data = e; //建立新的结点
s -> next = p -> next;
//“-> next”在赋值号右侧出现,可理解为指针域
//“-> next”在赋值号左侧出现,可理解为地址
p -> next = s;

/**
* 此算法为前插结点

LNode *q = L;
while (q -> next < p) {
q = q -> next;
}
s -> next = q -> next;
q -> next = s;

*/


return 0;
}

Status listDelete_ln(LNode *L, int i, elemType *e) {
//L是带头结点链表的头指针,在第i个结点之前删除元素,并将删除元素返回

LNode *p = L;
int j = 0;

while (p -> next && j < i-1) {
p = p -> next;
++j;
}

if (!(p -> next) || j > i-1) {
return ERROR;
}

LNode *q = p -> next;
p -> next = q -> next;
*e = q -> data;
free(q);

return *e;
}

Status listClear_ln(LNode *L) {

while ((L) -> next) {
LNode *p = (L) -> next;
(L) -> next = p -> next;
free(p);
}

return 0;
}

LinkList listCreate_ln_front(LNode *L) {
//从表尾到表头逆向建立单链表L,每次均在头结点之后插入元素
LNode *s;elemType x;
L=(LNode *)malloc(sizeof(LNode)); //创建头结点
L->next=NULL; //初始为空链表
scanf("%c", &x); //输入结点的值
while(x!='\n') { //输入 9999 表示结束
s=(LNode*)malloc(sizeof(LNode) ); //创建新结点
s->data=x;
s->next=L->next;
L->next=s; //将新结点插入表中,L为头指针
scanf ("%c", &x);
} //while 结束
return L;
}

LinkList listCreate_ln_latter_no(LNode *L) {
//无头结点的单链表
LNode *L = NULL;
LNode *s, *r = NULL;
int x;

while ((scanf("%d", &x))) {

s = (LNode *)malloc(sizeof(LNode));
s -> data = x;

if (L == NULL) {
L = s;
} else {
L -> next = s;
}

r = s;
}

if (r != NULL) {
r -> next = NULL;//将最后一个结点的指针域设为空
}

return L;
}

LinkList listCreate_ln_latter_yes(LNode *L) {
//有头结点的单链表

//从表头到表尾正向建立单链表L,每次均在表尾插入元素
elemType x; // 设元素类型为整型
L=(LinkList)malloc(sizeof(LNode));
LNode *s, *r=L; //r 为表尾指针
scanf ("%c", &x); //输入结点的值
while (x!='\n') { //输入 9999 表示结束
s=(LNode *)malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s; //r指向新的表尾结点
scanf ("%c", &x);
}
r->next = NULL; //尾结点指针置空
return L;

}

int printLinkList(LNode *L) {
LNode *p = L -> next;
while (p != NULL) {
printf("%d\t", p -> data);
p = p -> next;
}
printf("\n");
}

int lengthLinkList(LNode *L) {
int num = 0;
LNode *p = L -> next;
while (p != NULL) {
num++;
p = p -> next;
}
return num;
}

main.c

1
2
3
4
5
6
7
8
9
10
#include "ListAPI.h"
int main(int argc, const char * argv[]) {
//以初始化单链表为例
LNode *L;
...
...
...
return 0;
//在运行插入删除操作时要手动管理链表长度
}

本人亲测上诉函数应该没有问题,若发现有问题请发送邮件到630991493@qq.com,谢谢指出bug并同时欢迎交流