1 #include<stdlib.h>
2 #include<stdio.h>
3 #define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
4 #define LISTINCREMENT 10 //线性表存储空间的分配增量
5 typedef int ElemType; //定义基本元素类型 ,将 整型 int 关键字 重新命名为 Elemtype,int 和 Elemtype 代表的类型是一样的,声明和定义的变量是等价的,都是整型
6 typedef int Status; //定义基本返回值类型 解释同上
7 /* typedef 用法:
8 typedef 类型定义标识符,作用是 为一个数据类型或者结构重新定义一个名称;
9 定义一种类型的别名,而不只是简单的宏替换。不同于宏,它不是简单的字符串替换,可以用作同时声明指针型的多个对象。
10 在需要大量指针的地方,typedef的方式更省事。
11 */
12
13 typedef struct {
14 ElemType* elem; //指定线性表初始地址
15 int length; //定义当前长度
16 int listsize; //当前分配的存储容量(一个ElemType类型的字节*存储的ElemType类型数据的个数)
17 }SqList;
18
19 //创建表
20 Status InitList_Sq(SqList &L) {
21 /*Status是函数返回值类型
22 InitList_Sq是函数名
23 括号中是的是形参,SqList &L 表示L是引用一个SqList类型的实参*/
24 L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));//动态分配空间
25 /*将L.elem这个指针指向一块通过malloc函数分配的内存的地址
26 这个内存的大小为Elemtype这个结构体的size*LIST_INIT_SIZE的乘积这么大
27 malloc 是用于分配指定size的内存的库函数
28 malloc的语法是:指针名=(数据类型*)malloc(长度),(数据类型*)表示指针. */
29 if (!L.elem)
30 exit(1); //存储分配失败 ,return与exit区别:return返回函数值,是关键字; exit 是一个函数。
31 L.length = 0;
32 L.listsize = LIST_INIT_SIZE;
33 return true;//如果L.elem为空返回 1(false)否则为下面的语句
34 }
35
36 //插入数据
37 Status ListInsert_Sq(SqList &L, int i, ElemType e)//定义参数
38 {
39 if (i <1 || i> L.length + 1)//只能挨个的存入(比如刚把第一个位置存入元素就想在第三个位置存入元素,这样是不行的)
40 return false;
41 if (L.length >= L.listsize) //在使用这一次插入函数之前已经插满了元素,则在这一次使用函数的时候首先要开辟更多的空间
42 {
43 ElemType *newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
44 /*先释放原来L.elem所指内存区域,
45 按照(L.listsize+LISTINCREMENT)*sizeof(ElemType)的大小重新分配空间其中LISTINCREMENT为 2(#define LISTINCREMENT 2 ),
46 同时将原有数据从头到尾拷贝到新分配的内存区域,并返回该内存区域的首地址。即重新分配存储器块。*/
47 if (!newbase)
48 exit(1); //存储分配失败
49 L.elem = newbase;//新基址
50 L.listsize += LISTINCREMENT; //增加新的存储容量
51 }
52
53 ElemType *q = &(L.elem[i - 1]);//q为线性表初始地址
54
55 for (ElemType *p = &(L.elem[L.length - 1]); p >= q; --p)//把L线性表的最后元素的地址赋给p(length只在每增加一个元素的时候+1)
56 *(p + 1) = *p; //插入位置及之后的元素右移
57
58 *q = e; //插入e
59 ++L.length; //表长增1
60 return true;
61 }
62
63 //删除元素
64 Status ListDelet_Sq(SqList &L, int i, ElemType &e) {
65 if (i<1 || i>L.length) { return false; }
66 ElemType* p = &(L.elem[i - 1]);//第i个元素的位置赋给p
67 e = *p;//把第i个元素的值赋给e
68 ElemType* q = &L.elem[L.length - 1];//最后一个元素的地址赋给q arr[5]
69 for (++p; p <= q; p++) {//把表中i之后的元素依次向前移一位
70 *(p - 1) = *p;
71 }
72 L.length--;//表长减一
73 return true;
74 }
75
76 //比较两个元素是否相同
77 Status compare(ElemType a, ElemType b) {
78 if (a == b)
79 return true;
80 else
81 return false;
82 }
83
84 //定义函数指针并赋初值:compare函数的地址
85 Status(*com)(ElemType, ElemType) = &compare;
86
87 //查找表中e与某函数满足条件的第一个元素的位置
88 int LocalteElem_Sq(SqList L, ElemType e, Status(*compare)(ElemType, ElemType)) {
89 int i = 1;//i为第一个满足条件的元素的位置
90 int* p = L.elem;//把线性表的初始位置给指针p
91 while (i <= L.length && !(*compare)(*p++, e)) {
92 i++;//如果不满足条件则把指针的位置向前移一位
93 }
94 if (i <= L.length)
95 return i;//如果i的值没有大于线性表的大小,则返回满足条件的元素的位序
96 else
97 return 0;//否则返回0
98 }
99
100
101 //输出线性表中的数据
102 Status printf(SqList list) {
103 for (int a = list.length, i = 0; i < a; i++)
104 {
105 printf("%d\t", list.elem[i]);//循环输出每个元素
106 }
107 printf("\n");//无意义,美观输出界面
108 return true;
109 }
110
111 void sc(int a) {
112 a--;
113 printf("a的值是%d:\n",a);
114 }
115
116 int main()
117 {
118 int asc = 0;
119 sc(asc);
120 printf("a的值是%d\n",asc);
121
122 SqList L;//创建一个表头
123 InitList_Sq(L);//创建表
124
125 printf("分别插入数据2,3,4,5,6:\n");
126 ListInsert_Sq(L, 1, 2);//插入数据(在L这个表中,把‘2’插入到L的第1个位置)
127 ListInsert_Sq(L, 2, 3);
128 ListInsert_Sq(L, 3, 4);
129 ListInsert_Sq(L, 4, 5);
130 ListInsert_Sq(L, 5, 6);
131 /*
132 {//验证无法跳着存储
133 ListInsert_Sq(L, 5, 1);
134 ListInsert_Sq(L, 6, 1);
135 ListInsert_Sq(L, 7, 1);
136 只能挨到一个一个的存储
137 }*/
138
139 int a = 0;
140 ListDelet_Sq(L, 1, a);//删除L表中第1个元素并把这个值赋给a
141 printf("删除的元素是:%d\n", a);
142
143 int b = 3;
144 printf("在表L中第一个值为%d的元素的位序为:%d\n", b, LocalteElem_Sq(L, b, com));
145 printf("已存入元素个数:%d\n这几个元素分别是:", L.length);
146 printf(L);
147
148 system("pause");
149 return 0;
150 }