@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 }
從靜態順序表中刪除元素

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 }
遍歷靜態順序表

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

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 }
效果圖
動態順序表的實現
定義一個動態順序表
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 }
向動態順序表中插入元素

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 }
從動態順序表中刪除元素

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 }
遍歷動態順序表

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 }
銷毀一個動態順序表

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 }
清空一個動態順序表

1 //清空一個動態順序表 2 void ClearList(SqList* S) { 3 //令元素個數為 0 4 S->len = 0; 5 printf("已清空\n"); 6 }
判斷動態順序表是否為空

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 }
獲取動態順序表上指定位置的值

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 }
在動態順序表中查找指定值

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 }
在動態順序表中查找指定元素的前驅

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 }
在動態順序表中查找指定元素的后繼

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 }
測試

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 }
效果圖