数据结构:静态顺序表和动态顺序表


@Sock对静态顺序表和动态顺序表的总结

简单概括他们的异同点


相同点:内存空间连续, 数据顺序存储

不同点:它们所占内存空间的位置不同, 静态定义一个顺序表, 顺序表所占的内存空间开辟在内存的静态区, 即所谓的函数栈上, 随着函数调用的结束, 这块内存区域会被系统自动回收; 而动态生成一个顺序表, 顺序表所占的内存空间开辟在内存的动态区, 即所谓的堆内存上, 这块区域不会随着函数调用的结束被系统自动回收, 而是需要程序员主动去释放它.

 

各自优点(个人认为)


静态顺序表: 操作简单, 不用手动释放其内存空间, 不存在内存泄漏

动态顺序表: 可以动态开辟内存空间, 操作灵活, 避免不必要的开销

 

静态顺序表的实现

定义一个静态顺序表

1 //定义一个静态顺序表
2 #define MAXSIZE 100
3 typedef int ElemType;
4 ElemType SqList[MAXSIZE];
5 int len;

 

向静态顺序表中插入元素

 1 //向静态顺序表中插入元素
 2 void InsertElem(ElemType* S, int* len, int pos, ElemType e) {
 3     //判断插入位置是否合理
 4     if (*len == MAXSIZE || pos < 1 || pos > *len + 1) {
 5         printf("表满或插入位置不合理\n");
 6         exit(0);
 7     }
 8     //调整插入位置, 准备插入指定元素
 9     for (int i = *len - 1; i >= pos - 1; --i) {
10         *(S + i + 1) = *(S + i);
11     }
12     //插入指定元素
13     *(S + pos - 1) = e;
14     //元素个数加 1
15     ++(*len);
16 }
InsertElem

 

从静态顺序表中删除元素

 1 //向静态顺序表中删除元素
 2 void DelElem(ElemType* S, int* len, int pos) {
 3     //判断删除位置是否合理
 4     if (pos < 1 || pos > *len) {
 5         printf("删除位置不合理\n");
 6         exit(0);
 7     }
 8     //调整删除位置, 准备删除指定元素
 9     for (int i = pos; i < *len; ++i) {
10         *(S + i - 1) = *(S + i);
11     }
12     //元素个数减 1
13     --(*len);
14 }
DelElem

 

遍历静态顺序表

1 //遍历顺序表
2 void Traverse(ElemType* S) {
3     for (int i = 0; i < len; ++i) {
4         printf("%d ", *(S + i));
5     }
6     printf("\n");
7 }
Traverse

测试

 1 #include <stdio.h>
 2 #include <windows.h>
 3 
 4 //定义一个静态顺序表
 5 #define MAXSIZE 100
 6 typedef int ElemType;
 7 ElemType SqList[MAXSIZE];
 8 int len;
 9 
10 //向静态顺序表中插入元素
11 void InsertElem(ElemType* S, int* len, int pos, ElemType e) {
12     //判断插入位置是否合理
13     if (*len == MAXSIZE || pos < 1 || pos > *len + 1) {
14         printf("表满或插入位置不合理\n");
15         exit(0);
16     }
17     //调整插入位置, 准备插入指定元素
18     for (int i = *len - 1; i >= pos - 1; --i) {
19         *(S + i + 1) = *(S + i);
20     }
21     //插入指定元素
22     *(S + pos - 1) = e;
23     //元素个数加 1
24     ++(*len);
25 }
26 
27 //向静态顺序表中删除元素
28 void DelElem(ElemType* S, int* len, int pos) {
29     //判断删除位置是否合理
30     if (pos < 1 || pos > *len) {
31         printf("删除位置不合理\n");
32         exit(0);
33     }
34     //调整删除位置, 准备删除指定元素
35     for (int i = pos; i < *len; ++i) {
36         *(S + i - 1) = *(S + i);
37     }
38     //元素个数减 1
39     --(*len);
40 }
41 
42 //遍历顺序表
43 void Traverse(ElemType* S) {
44     for (int i = 0; i < len; ++i) {
45         printf("%d ", *(S + i));
46     }
47     printf("\n");
48 }
49 
50 int main() {
51     len = 5;
52     for (int i = 0; i < len; ++i) {
53         *(SqList + i) = i + 1;
54     }
55     Traverse(SqList);
56     InsertElem(SqList, &len, 4, 100);
57     Traverse(SqList);
58     DelElem(SqList, &len, 4);
59     Traverse(SqList);
60     system("pause");
61     return 0;
62 }
main

效果图

 

 

动态顺序表的实现

定义一个动态顺序表

1 //定义一个动态顺序表
2 #define MAXSIZE 100
3 #define LISTINCREMENT 10
4 typedef int ElemType;
5 typedef struct SqList {
6     ElemType* elem;
7     int len;
8     int listsize;
9 }SqList;

初始化

 1 //初始化一个动态顺序表
 2 void InitList(SqList* S) {
 3     //动态生成了一个指定大小的顺序表
 4     S->elem = (ElemType*)malloc(MAXSIZE * sizeof(ElemType));
 5     if (!S->elem) {
 6         printf("创建失败\n");
 7         exit(0);
 8     }
 9     S->len = 0;
10     S->listsize = MAXSIZE;
11 }
InitList

向动态顺序表中插入元素

 1 //向动态顺序表中插入元素
 2 void InsertElem(SqList* S, int pos, ElemType e) {
 3     //判断插入位置是否合理
 4     if (pos < 1 || pos > S->len + 1) {
 5         printf("插入位置不合理\n");
 6         return;// exit(0);
 7     }
 8     //判断表是否为满
 9     if (S->len == S->listsize) {
10         S->elem = (ElemType*)realloc(S->elem, (S->listsize + LISTINCREMENT) * sizeof(ElemType));
11         S->listsize += LISTINCREMENT;
12     }
13     //调整插入位置, 准备插入指定元素
14     for (int i = S->len - 1; i >= pos - 1; --i) {
15         *(S->elem + i + 1) = *(S->elem + i);
16     }
17     //插入指定元素
18     *(S->elem + pos - 1) = e;
19     //元素个数加 1
20     ++S->len;
21 }
InsertElem

从动态顺序表中删除元素

 1 //从动态顺序表中删除元素
 2 void DelElem(SqList* S, int pos) {
 3     //判断删除位置是否合理
 4     if (pos < 1 || pos > S->len) {
 5         printf("删除位置不合理\n");
 6         return;// exit(0);
 7     }
 8     //调整删除位置, 准备删除指定元素
 9     for (int i = pos; i < S->len; ++i) {
10         *(S->elem + i - 1) = *(S->elem + i);
11     }
12     //元素个数减 1
13     --S->len;
14 }
DelElem

遍历动态顺序表

1 //遍历顺序表
2 void Traverse(SqList S) {
3     for (int i = 0; i < S.len; ++i) {
4         printf("%d ", *(S.elem + i));
5     }
6     printf("\n");
7 }
Traverse

销毁一个动态顺序表

1 //销毁一个动态顺序表
2 void DestroyList(SqList* S) {
3     //释放堆内存
4     free(S->elem);
5     S->elem = NULL;
6     S->len = 0;
7     S->listsize = 0;
8     printf("销毁成功\n");
9 }
DestroyList

清空一个动态顺序表

1 //清空一个动态顺序表
2 void ClearList(SqList* S) {
3     //令元素个数为 0
4     S->len = 0;
5     printf("已清空\n");
6 }
ClearList

判断动态顺序表是否为空

1 //判断动态顺序表是否为空
2 int IsEmpty(SqList S) {
3     if (S.len == 0) {
4         //printf("表为空\n");
5         return 1;
6     }
7     //printf("表不为空\n");
8     return 0;
9 }
IsEmpty

获取动态顺序表上指定位置的值

1 //获取动态顺序表上某个位置上的值
2 int GetElem(SqList S, int pos) {
3     //判断获取位置是否合理
4     if (pos < 1 || pos > S.len) {
5         printf("获取位置不合理\n");
6         return 0;// exit(0);
7     }
8     return *(S.elem + pos - 1);
9 }
GetElem

在动态顺序表中查找指定值

 1 //在动态顺序表中查找指定值
 2 void LocateElem(SqList S, ElemType e) {
 3     //遍历顺序表
 4     for (int i = 0; i < S.len; ++i) {
 5         if (*(S.elem + i) == e) {
 6             printf("找到了该元素, 它是第 %d 个元素\n", i + 1);
 7             return;
 8         }
 9     }
10     printf("没有找到该元素\n");
11 }
LocateElem

在动态顺序表中查找指定元素的前驱

 1 //在动态顺序表中找某个元素的前驱
 2 ElemType ProriElem(SqList S, ElemType cur_e) {
 3     //判断是否为第一个元素
 4     if (*S.elem == cur_e) {
 5         printf("第一个元素没有前驱\n");
 6         return 0;
 7     }
 8     //从第二个元素开始查找
 9     for (int i = 1; i < S.len; ++i) {
10         if (*(S.elem + i) == cur_e) {
11             //返回该元素的前驱
12             return *(S.elem + i - 1);
13         }
14     }
15     printf("没有该元素\n");
16     return 0;
17 }
ProriElem

在动态顺序表中查找指定元素的后继

 1 //在动态顺序表中找某个元素的后继
 2 ElemType NextElem(SqList S, ElemType cur_e) {
 3     //判断是否为最后一个元素
 4     if (*(S.elem + S.len - 1) == cur_e) {
 5         printf("最后一个元素没后继\n");
 6         return 0;
 7     }
 8     //从头一直查到倒数第 2 个元素
 9     for (int i = 0; i < S.len - 1; ++i) {
10         if (*(S.elem + i) == cur_e) {
11             //返回该元素的后继    
12             return *(S.elem + i + 1);
13         }
14     }
15     printf("没有该元素\n");
16     return 0;
17 }
NextElem

测试

  1 #include <stdio.h>
  2 #include <windows.h>
  3 
  4 //定义一个动态顺序表
  5 #define MAXSIZE 100
  6 #define LISTINCREMENT 10
  7 typedef int ElemType;
  8 typedef struct SqList {
  9     ElemType* elem;
 10     int len;
 11     int listsize;
 12 }SqList;
 13 
 14 //初始化一个动态顺序表
 15 void InitList(SqList* S) {
 16     //动态生成了一个指定大小的顺序表
 17     S->elem = (ElemType*)malloc(MAXSIZE * sizeof(ElemType));
 18     if (!S->elem) {
 19         printf("创建失败\n");
 20         exit(0);
 21     }
 22     S->len = 0;
 23     S->listsize = MAXSIZE;
 24 }
 25 
 26 //向动态顺序表中插入元素
 27 void InsertElem(SqList* S, int pos, ElemType e) {
 28     //判断插入位置是否合理
 29     if (pos < 1 || pos > S->len + 1) {
 30         printf("插入位置不合理\n");
 31         return;// exit(0);
 32     }
 33     //判断表是否为满
 34     if (S->len == S->listsize) {
 35         S->elem = (ElemType*)realloc(S->elem, (S->listsize + LISTINCREMENT) * sizeof(ElemType));
 36         S->listsize += LISTINCREMENT;
 37     }
 38     //调整插入位置, 准备插入指定元素
 39     for (int i = S->len - 1; i >= pos - 1; --i) {
 40         *(S->elem + i + 1) = *(S->elem + i);
 41     }
 42     //插入指定元素
 43     *(S->elem + pos - 1) = e;
 44     //元素个数加 1
 45     ++S->len;
 46 }
 47 
 48 //从动态顺序表中删除元素
 49 void DelElem(SqList* S, int pos) {
 50     //判断删除位置是否合理
 51     if (pos < 1 || pos > S->len) {
 52         printf("删除位置不合理\n");
 53         return;// exit(0);
 54     }
 55     //调整删除位置, 准备删除指定元素
 56     for (int i = pos; i < S->len; ++i) {
 57         *(S->elem + i - 1) = *(S->elem + i);
 58     }
 59     //元素个数减 1
 60     --S->len;
 61 }
 62 
 63 //销毁一个动态顺序表
 64 void DestroyList(SqList* S) {
 65     //释放堆内存
 66     free(S->elem);
 67     S->elem = NULL;
 68     S->len = 0;
 69     S->listsize = 0;
 70     printf("销毁成功\n");
 71 }
 72 
 73 //清空一个动态顺序表
 74 void ClearList(SqList* S) {
 75     //令元素个数为 0
 76     S->len = 0;
 77     printf("已清空\n");
 78 }
 79 
 80 //判断动态顺序表是否为空
 81 int IsEmpty(SqList S) {
 82     if (S.len == 0) {
 83         //printf("表为空\n");
 84         return 1;
 85     }
 86     //printf("表不为空\n");
 87     return 0;
 88 }
 89 
 90 //获取动态顺序表上某个位置上的值
 91 int GetElem(SqList S, int pos) {
 92     //判断获取位置是否合理
 93     if (pos < 1 || pos > S.len) {
 94         printf("获取位置不合理\n");
 95         return 0;// exit(0);
 96     }
 97     return *(S.elem + pos - 1);
 98 }
 99 
100 //在动态顺序表中查找指定值
101 void LocateElem(SqList S, ElemType e) {
102     //遍历顺序表
103     for (int i = 0; i < S.len; ++i) {
104         if (*(S.elem + i) == e) {
105             printf("找到了该元素, 它是第 %d 个元素\n", i + 1);
106             return;
107         }
108     }
109     printf("没有找到该元素\n");
110 }
111 
112 //在动态顺序表中找某个元素的前驱
113 ElemType ProriElem(SqList S, ElemType cur_e) {
114     //判断是否为第一个元素
115     if (*S.elem == cur_e) {
116         printf("第一个元素没有前驱\n");
117         return 0;
118     }
119     //从第二个元素开始查找
120     for (int i = 1; i < S.len; ++i) {
121         if (*(S.elem + i) == cur_e) {
122             //返回该元素的前驱
123             return *(S.elem + i - 1);
124         }
125     }
126     printf("没有该元素\n");
127     return 0;
128 }
129 
130 //在动态顺序表中找某个元素的后继
131 ElemType NextElem(SqList S, ElemType cur_e) {
132     //判断是否为最后一个元素
133     if (*(S.elem + S.len - 1) == cur_e) {
134         printf("最后一个元素没后继\n");
135         return 0;
136     }
137     //从头一直查到倒数第 2 个元素
138     for (int i = 0; i < S.len - 1; ++i) {
139         if (*(S.elem + i) == cur_e) {
140             //返回该元素的后继    
141             return *(S.elem + i + 1);
142         }
143     }
144     printf("没有该元素\n");
145     return 0;
146 }
147 
148 //遍历顺序表
149 void Traverse(SqList S) {
150     for (int i = 0; i < S.len; ++i) {
151         printf("%d ", *(S.elem + i));
152     }
153     printf("\n");
154 }
155 
156 int main() {
157     SqList S1;
158     InitList(&S1);
159     //填写 5 个数据
160     for (int i = 0; i < 5; ++i) {
161         *(S1.elem + i) = i + 1;
162         ++S1.len;
163     }
164     Traverse(S1);
165     InsertElem(&S1, 4, 100);
166     Traverse(S1);
167     int value = GetElem(S1, 4);
168     printf("%d\n", value);
169     LocateElem(S1, 100);
170     int prori_e = ProriElem(S1, 100);
171     printf("%d\n", prori_e);
172     int next_e = NextElem(S1, 100);
173     printf("%d\n", next_e);
174     DelElem(&S1, 4);
175     Traverse(S1);
176     system("pause");
177     return 0;
178 }
main

效果图

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM