1 # ifndef _TEST_H_
2 # define _TEST_H_
3 # include <stdio.h>
4 # include <stdlib.h>
5 # include <stdbool.h>
6 # define LIST_INIT_SIZE 10 //线性表存储空间初始分配
7 # define LIST_INCREMENT 2 //线性表存储空间空间分配增量
8 # define ERROR 0 //失败
9 # define OK 1 //成功
10
11 typedef int ElemType; // 抽象数据类型
12 typedef int Status;
13
14 typedef struct sqlist
15 {
16 ElemType * elem; //存储空间基址
17 int length; //连表元素个数
18 int listsize; //但前分配空间个数
19 }SqList;
20
21
22 # endif
文件名为:test.h的头文件
1 # include "test.h"
2
3
4 void InitList(SqList * L) //构造一个空的线性表L
5 {
6 L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType) * 10);
7 if(!L->elem) //内存分配失败
8 exit(1);
9 L->length = 0; //空表长度为0
10 L->listsize = LIST_INIT_SIZE; //初始存储容量
11 }
12
13 bool ListInsert(SqList * L, int i, ElemType e)
14 {
15 ElemType * newbase, *p, *q;
16 if(i < 1 || i > L->length + 1) //i的值不合法
17 return false;
18
19
20 if(L->length == L->listsize) //但前存储空间已满,增加分配
21 {
22 newbase = (ElemType *)realloc(L->elem,sizeof(ElemType) * 10 + 2);
23 if(!newbase) //存储空间分配失败
24 exit(1);
25 L->elem = newbase;
26 L->listsize += LIST_INCREMENT; //增加存储容量
27 }
28
29 p = L->elem + i - 1; //p为插入位置
30
31 for(q = L->elem + L->length - 1; q >= p; q--) //插入位置之后的元素往右移
32 *(q+1) = *q;
33
34 *p = e; //插入e
35 L->length++; //表长增1
36 return true;
37 }
38
39 void print(ElemType c) //以十进制输出元素
40 {
41 printf("%d ", c);
42 }
43
44 void TraverseList(SqList * L, void(*visit)(ElemType)) //线性表存在;对每个元素依次调用visit函数
45 {
46 ElemType *p = L->elem; //p指向第一个元素
47 int i;
48
49 for(i = 1; i <= L->length; i++) //从表第一个元素到最后一个元素
50 visit(*p++); //对每一个元素调用visit
51
52 printf("\n");
53 }
54
55 int ListLength(SqList L) //返回L表中元素的个数
56 {
57 return L.length;
58 }
59
60 void ListClear(SqList * L) //顺序线性表存在 ,将L表置成空表
61 {
62 L->length = 0;
63 }
64
65 void DestroyList(SqList * L)
66 //顺序线性表已存在, 销毁线性表L
67 {
68 free(L->elem); //释放L.elem所指向的存储空间
69 L->elem = NULL; //L.elem不再指向任何存储单元
70 L->length = 0;
71 L->listsize = 0;
72 }
73
74 bool ListEmpty(SqList * L) //检测L链表是否为空 空返回true 不空返回false
75 {
76 if(L->length == 0)
77 return true;
78 else
79 return false;
80 }
81
82 bool GetElem(SqList * L, int i, ElemType * e) //用e返回l中第i个元素
83 {
84 if(i<1 || i > L->length) //i不再L表的范围之内
85 return false;
86
87 *e = *(L->elem+i-1); //将L表中的第i个值赋给e
88 return true;
89 }
90
91 bool equal(ElemType c1, ElemType c2) //判断俩者关系是否相等 是true 否false
92 {
93 if(c1 == c2)
94 return true;
95 else
96 return false;
97 }
98
99 bool sq(ElemType c1, ElemType c2) //判断平方关系。
100 {
101 if(c1 == c2 * c2)
102 return true;
103 else
104 return false;
105 }
106
107 Status LocateElem(SqList * L, ElemType e, bool(*compare)(ElemType, ElemType)) //返回L中满足关系xompare数据元素的位序
108 {
109 ElemType * p = L->elem; //p的初始值为第一个元素的位置
110 int i = 1; //i的初始值为第一个元素的位序
111
112 while(i <= L->length && !compare(*p++, e)) //i没有超出L表范围且 未找到满足关系的数据元素
113 i++; //继续向后找
114
115 if(i <= L->length) //找到满足关系的数据元素
116 return i; //返回其位序
117 else
118 return 0; //未找到满足关系的元素
119 }
120
121 Status PriorElem(SqList * L, ElemType cur_e, ElemType * pre_e)
122 //若cur_e是L的元素且不是第一个则返回前驱,否则操作失败
123 {
124 ElemType * p = L->elem+1; //p指向第二个元素
125 int i = 2; // 从第二个元素开始
126
127 while(i <= L->length && *p != cur_e) //i未超出表的范围且未找着以cur_e的元素
128 {
129 p++; // p指向下一个元素
130 i++; // 计数器加1
131 }
132
133 if(i > L->length) //到表结束处还未找到值为cur_e的元素
134 return ERROR; //操作失败
135 else //找到值为cur_e的元素,并由p指向
136 {
137 *pre_e = *--p; //把指向p的前一个元素赋值给Pre_e(前驱)
138 return OK; //操作成功
139 }
140 }
141
142 Status NextElem(SqList * L, ElemType cur_e, ElemType * next_e)
143 //若cur_e是L的元素且不是最后一个则返回后驱,否则操作失败
144 {
145 int i = 1; //从第一个元素开始
146 ElemType * p = L->elem; //p指向第一个元素
147
148 while(i < L->length && *p != cur_e) //i到表尾未找到值为cur_e的元素
149 {
150 i++; //技术驱加1
151 p++; //p指向下一个元素
152 }
153
154 if(i == L->length) //到表尾的前一个元素还未找到值为cur_e的元素
155 return ERROR; //操作失败
156 else // 找到值为cur_e的元素,并由p指向
157 {
158 *next_e = *++p; //p把后继元素赋给next_e
159 return OK; //操作成功
160 }
161 }
162
163 Status ListDelete(SqList * L, int i, ElemType * e)
164 {
165 ElemType * p, *q;
166 if(i < 1 || i > L->length)
167 return ERROR; //i的值不合法
168
169 p = L->elem + i -1; //p指向要删除的元素地址
170 *e = *p; //将要删除的元素赋给e
171 q = L->elem + L->length -1; //q指向L元素的最后一个地址
172 for(p++; p <= q; p++) //被删除位置之后向左移动到最后一个
173 *(p-1) = *p;
174 L->length--; //长度减1
175 return OK; //操作成功
176 }
- 文件为:text.c的原代码文件
1 # include <stdio.h>
2 # include "test.h"
3
4 void print(ElemType c);
5 void equal(ElemType, ElemType);
6 bool sq(ElemType, ElemType);
7
8 int main(void)
9 {
10 SqList La, Lb;
11 Status i;
12 int j, k;
13 ElemType e, e0;
14
15 InitList(&La); //初始化线性表La
16 printf("初始化La后:La.length = %d, La.listsize = %d\n", La.length, Lb.listsize);
17 for(j = 1; j <= 5; j++)
18 i = ListInsert(&La, 1, j); // 在La表头插入元素
19 printf("在La插入1~5后:*L.elem = ");
20 for(j = 1; j <= 5; j++)
21 printf("%d ", *(La.elem+j-1)); //依次输出表中La中的元素
22 printf("\n调用TraverseList函数再次输出元素");
23 TraverseList(&La, print); //依次对La中的元素调用print元素进行输出
24 i = ListEmpty(La); //检测是否为空
25 printf("La.length = %d \t La.listsize = %d\n", La.length, La.listsize);
26 printf("La.elem = %p, La是否为空i=%d\n", La.elem, i);
27 ListClear(&La);
28 i = ListEmpty(La); //再次检测是否为空
29 printf("La.length = %d\t La.listsize = %d\n", La.length, La.listsize);
30 printf("La.elem = %p\t La是否为空i = %d\n", La.elem, i);
31 for(j = 1; j <= 10; j++)
32 i = ListInsert(&La, j, j); //在La表尾插入j
33 printf("在表尾依次插入1~10后L:");
34 TraverseList(&La, print); //依次输出La表中的元素
35 printf("La.length = %d\t La.listsize = %d\t La.elem = %p\n", La.length, La.listsize, La.elem);
36 ListInsert(&La, 1, 0); //在La表头插入0 增加存储空间
37 printf("在la表头插入0后La.length = %d La.listsize = %d La.elem = %p\n", La.length, La.listsize, La.elem);
38 GetElem(&La, 5, &e); //将La第5个元素赋值给e
39 printf("La的第5个元素为%d\n", e);
40 TraverseList(&La, print);
41 for(j = 10; j <= 11; j++)
42 {
43 k = LocateElem(&La, j, equal); //查找La表中与j相等的元素并将位序赋给k
44 if(k) //k不为0表明有符合条件的元素
45 printf("第%d个值为%d\n", k, j);
46 else //k为0没有符合条件的元素
47 printf("没有值为%d的元素\n",j);
48 }
49 for(j = 3; j <= 4; j++) //测试两个数据
50 {
51 k = LocateElem(&La, j, sq); //查找La表中与j的平方相等的元素,并将位序赋给K
52 if(k) //k不为0表明有符合条件的元素
53 printf("第%d个元素的值为%d的平方\n", k, j);
54 else //k为0没有符合条件的元素
55 printf("没有值为%d的平方元素\n", j);
56 }
57 for(j = 1; j <= 2; j++) //测试前两个数据
58 {
59 GetElem(&La, j, &e0); //将La中第J个元素赋给e0
60 i = PriorElem(&La, e0, &e); //求e0的前驱,如成功赋给e
61 if(i == ERROR) //操作失败
62 printf("元素%d无前驱\n", e0);
63 else //操作成功
64 printf("元素%d的前驱为%d\n", e0, e);
65 }
66 for(j = ListLength(La) - 1; j <= ListLength(La); j++)//最后两个元素
67 {
68 GetElem(&La, j, &e0); //将La中第J个元素赋给e0
69 i = NextElem(&La, e0, &e); //求e0的后驱,如成功赋给e
70 if(i == ERROR) //操作失败
71 printf("元素%d无后继元素\n", e0);
72 else //操作成功
73 printf("元素%d的后继元素为%d\n", e0, e);
74 }
75 k = ListLength(La); //求La的表长并赋给k
76 for(j = k+1; j >= k; j--)
77 {
78 i = ListDelete(&La, j, &e);//删除第j个数据
79 if(i == ERROR) //操作失败
80 printf("删除第%d个元素失败\n", j);
81 else //操作成功
82 printf("删除%d个元素成功其值为%d\n", j, e);
83 }
84 TraverseList(&La, print); //再次输出表中元素
85 DestroyList(&La); //销毁表La
86 printf("销毁La后L.length = %d L.listsize = %d L.elem = %p\n", La.length, La.listsize, La.elem);
87
88 return 0;
89 }
- 文件为:main.c主函数文件
运行:gcc text.c main.c -o main 生成main可执行文件 在linux : ./main运行