1. 顺序表概念及结构
1.1 线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表,链表,栈,队列,字符串......
线性表在逻辑上是线性结构,也就是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
2. 顺序表分类
2.1 顺序表和数组的区别
顺序表的底层结构是数组,对数组的封装,实现了常用的增删改查等接口。
2.2 顺序表分类
2.2.1 静态顺序表(使用定长数组存储元素)

Typedef int SLDataType;是将整型int命名为SLDataType,要知道数据表可不一定只存储整型数据啊,当我们需要更改数据类型时,只需要把Int改变一下就行了,VS2022上虽然有一键替换功能,但最好不用,因为不可控元素太多,容易使程序产生意想不到的结果 。
#define N 6中的define 定义宏,简单来说就是把N替代6再输入N时即代表为6。
剩下的结构体包含了整个静态表插入的数据及有效数据个数。
缺陷:
由于这种顺序表不可动态申容,故容量从一开始就规定好了容量,就会导致空间给少了不够用,给多了照成空间浪费。
2.2.2 动态顺序表(按需申请)

动态顺序表中结构体定义了有效数据个数和空间容量。
相较就静态顺序表而言,动态顺序表空间利用率更高,但仍有浪费。
故而我们主要来实现一下动态顺序表。
3. 动态顺序表的实现
动态顺序表所需头文件如下,从代码中我们不难看出顺序表的功能,有增删查改等功能。
1. #pragma once
2. include<stdio.h>
3. #include<stdlib.h>
4. #include<assert.h>
5. //定义顺序表的结构
6.
7.
8. #define N 100
9. //静态顺序表
10. struct SeqList
11. {
12. int arr[N];
13. int size;//有效数据个数
14. };
15.
16.
17. typedef int SLDataType;
18. //动态顺序表
19. typedef struct SeqList//sequence:顺序的;List:列表 仅是个名字,无特殊含义
20. {
21. SLDataType* arr;
22. int size;//有效数据个数
23. int capacity;//空间大小
24. }SL;
25.
26. typedef struct SeqList SeqList;
27. SeqList s1;
28. 顺序表初始化
29. void SLINit(SL* ps);
30. //顺序表的销毁
31. void SLDestroy(SL* ps);
32. void SLPrint(SL s);//由于并不改变顺序表中内容,所以可以不用传指针(用于查看顺序表中功能是否可以正常使用)
33. //头部插入 / 尾部插入
34. void SLPushBack(SL* ps, SLDataType);
35. void SLPushFront(SL* ps, SLDataType);
36. //头部删除/尾部删除
37. void SLPopback(SL* ps);
38. void SLPopFront(SL* ps);
39. //指定位置之前插入/删除数据
40. void SLInsert(SL* ps, int pos, SLDataType x);
41. void SLErace(SL* ps, int pos);
42. int SLFind(SL* ps, SLDataType x);
3.1 顺序表初始化
1. //顺序表初始化
2. void SLInit(SL* ps)
3. {
4. assert(ps);
5. ps->arr = NULL;
6. ps->size = ps->capacity = 0;
7. }
3.2 顺序表的销毁
1. //顺序表的销毁
2. void SLDestroy(SL* ps)
3. {
4. if (ps->arr)
5. {
6. free(ps->arr);
7. }
8. ps->arr = NULL;
9. ps->size = ps->capacity = 0;
10. }
3.3 顺序表的打印
1. void SLPrint(SL s)
2. {
3. for (int i = 0; i < s.size; i++)
4. {
5. printf("%d ", s.arr[i]);
6. }
7. printf("\n");
8. }
3.4 顺序表的尾部/头部插入
1. //检查容量并扩容
2. void SLCheckCapacity(SL* ps)
3. {
4. assert(ps);
5. if (ps->capacity == ps->size)
6. {
7. int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
8. SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity *
sizeof(SLDataType));
9. if (tmp == NULL)
10. {
11. perror("realloc fail!");
12. exit(1);
13. }
14. ps->arr = tmp;
15. ps->capacity = newcapacity;
16. }
17. }
18. //尾插
19. void SLPushBack(SL* ps, SLDataType x)
20. {
21. assert(ps);
22. SLCheckCapacity(ps);
23. ps->arr[ps->size++] = x;
24. }
25. //头插
26. void SLPushFront(SL* ps, SLDataType x)
27. {
28. assert(ps);
29. SLCheckCapacity(ps);
30. for (int i = ps->size; i > 0; i--)
31. {
32. ps->arr[i] = ps->arr[i - 1];
33. }
34. ps->arr[0] = x;
35. ps->size++;
36. }
3.5 顺序表的尾部/头部删除
1. void SLPopBack(SL* ps)
2. {
3. assert(ps && ps->size);
4. --ps->size;
5. }
6. void SLPopFront(SL* ps)
7. {
8. assert(ps && ps->size);
9. for (int i = 0; i < ps->size; i++)
10. {
11. ps->arr[i] = ps->arr[i + 1];
12. }
13. ps->size--;
14. }
3.6 顺序表在任意位置插入数据
1. void SLInsert(SL* ps, int pos, SLDataType x)
2. {
3. assert(ps);
4. SLCheckCapacity(ps);
5. assert(pos >= 0 && pos <= ps->size);
6. for (int i = ps->size;i>pos;i--)
7. {
8. ps->arr[i] = ps->arr[i-1];
9. }
10. ps->arr[pos] = x;
11. ps->size++;
12. }
3.7 顺序表删除任意位置的数据
1. void SLInsert(SL* ps, int pos, SLDataType x)
2. {
3. assert(ps);
4. SLCheckCapacity(ps);
5. assert(pos >= 0 && pos <= ps->size);
6. for (int i = ps->size;i>pos;i--)
7. {
8. ps->arr[i] = ps->arr[i-1];
9. }
10. ps->arr[pos] = x;
11. ps->size++;
12. }
3.8 顺序表中数据的查找
1. int SLFind(SL* ps, SLDataType x)
2. {
3. assert(ps);
4. for (int i = 0; i < ps->size; i++)
5. {
6. if (ps->arr[i] == x)
7. {
8. return i;
9. }
10. }
11. return -1;
12. }
367

被折叠的 条评论
为什么被折叠?



