靜態鏈表是利用一維數組實現邏輯上的單鏈表結構,結點的邏輯上相鄰但物理位置上不一定相鄰,因為內存分配上是一次性的,故稱為靜態。
特點:
- 預先需要一片連續的存儲空間;
- 非隨機存取;
- 無現成的“內存”分配和回收函數,得自己實現;
- 最多存儲MAXSIZE - 1個數據;
核心包含了兩個鏈表:
- 數據鏈表(初始化完成后需記住頭結點,一般為數組的第1個分量)
- 備用的空閑鏈表(數組的第0個分量是備用鏈表的頭結點)
- 注意邏輯位序和物理位序,實際上並沒有利用物理位序的使用操作,牢牢記住它只是一個單鏈表
這兩個鏈表都需要自己維護。

核心函數 :
- "內存"申請函數 int Malloc_SL();該函數返回申請的結點下標。
- "內存"釋放函數void Free_SL(int k);釋放邏輯位序k。
注意函數:
- void InitSpace_SL();該函數初始化鏈表空間,不做其他操作;
- int InitList_SL(SLinkList *h);該函數初始化數據鏈表並返回數據鏈表的頭結點,這個頭結點h非常重要,書本上沒有這個函數的介紹,導致有些人搞不懂對數據鏈表的操作該如何進;
Status.h文件
#ifndef STSTUS_H #define STSTUS_H #define TRUE 1 //真 #define FALSE 0 //假 #define YES 1 //是 #define NO 0 //否 #define OK 1 //通過 #define ERROR 0 //錯誤 #define SUCCESS 1 //成功 #define UNSUCCESS 0 //失敗 #define INFEASIBLE -1 //不可行 #define OVERFLOW -2 //堆棧上溢 #define UNDERFLOW -3 //堆棧下溢 typedef int Status; #define PressEnter \ {\ fflush(stdin);\ printf("Press Enter...");\ getchar();\ fflush(stdin);\ } #endif
StaticLinkedList.h文件
1 #ifndef STATICLINKEDLIST_H_ 2 #define STATICLINKEDLIST_H_ 3 4 #include "Status.h" 5 6 #define MAXSIZE 30 7 typedef int ElementType; 8 typedef int SLinkList; 9 10 typedef struct 11 { 12 ElementType data; 13 int cur; 14 }Component[MAXSIZE]; 15 16 17 18 //初始化,將一維數組Space中各分量鏈成一個大的備用空間 19 void InitSpace_SL(); 20 21 //為插入的輸入申請空間,從備用空間取得一個結點,返回分配結點下標 22 int Malloc_SL(); 23 24 //將下標為k的空閑結點回收 25 void Free_SL(int k); 26 27 //初始化靜態鏈表,建立頭結點,返回頭結點下標 28 int InitList_SL(SLinkList *h); 29 30 //置空 31 Status ClearList_SL(SLinkList h); 32 33 //銷毀 34 void DestroyList_SL(SLinkList* h); 35 36 //判空 37 Status ListEmpty_SL(SLinkList h); 38 39 //求長 40 int ListLength_SL(SLinkList h); 41 42 //取值 43 //h--頭結點,i--邏輯位置(1->maxsize-2),e--返回值 44 Status GetElem_SL(SLinkList h, int i, ElementType* e); 45 46 //返回元素e的位序 47 int LocateElem_SL(SLinkList h, ElementType e); 48 49 //前驅 50 //找值為cur_e的結點的前一個結點的值 51 Status PriorElem_SL(SLinkList h, ElementType cur_e, ElementType* pre_e); 52 53 //后繼 54 Status NextElem_SL(SLinkList h, ElementType cur_e, ElementType* next_e); 55 56 //插入 57 //在邏輯上第i個位置前插入數據,使其成為第i個位置 58 //i從1開始 59 Status ListInsert_SL(SLinkList h, int i, ElementType e); 60 61 //刪除 62 Status ListDelete_SL(SLinkList h, int i, ElementType* e); 63 64 //遍歷 65 Status ListTraverse_SL(SLinkList h, void(Visit)(ElementType)); 66 67 #endif
StaticLinkedList.cpp文件
1 #include "stdafx.h" 2 #include <cstdlib> 3 4 #include "StaticLinkedList.h" 5 6 //定義靜態鏈表空間 7 Component Space; 8 9 void InitSpace_SL() 10 { //初始化備用空間,形成備用鏈表 11 12 for (size_t i = 0; i < MAXSIZE - 1; ++i) //將0號單元做備用空間的起始結點 13 { 14 Space[i].cur = i + 1; //各空間結點邏輯上首尾相連 15 } 16 Space[MAXSIZE - 1].cur = 0; //最后一個結點下標指向NULL = 0,相當於鏈表的尾指針 17 } 18 19 int Malloc_SL() 20 { 21 int i = Space[0].cur; 22 23 if (Space[0].cur) 24 { 25 //將申請到的空間從備用鏈表空間中斷開,並為下一個空閑結點做准備,即將下一個空閑結點鏈接到s[0]下 26 Space[0].cur = Space[i].cur; 27 return i; //返回申請到的空間下標 28 } 29 return 0; //申請失敗返回0 30 } 31 32 void Free_SL(int k) 33 { 34 Space[k].cur = Space[0].cur; //將k結點的下個結點置為備用鏈表的第一個結點 35 Space[0].cur = k; //將K結點置為備用空間的第一個結點 36 } 37 38 int InitList_SL(SLinkList * h) 39 { 40 *h = Malloc_SL(); //創建頭結點 41 if (!(*h)) 42 { 43 exit(OVERFLOW); //空間已滿 44 } 45 46 Space[*h].cur = 0; //頭結點游標置為0 47 return OK; 48 } 49 50 Status ClearList_SL(SLinkList h) 51 { 52 int p; 53 if (!h) 54 { 55 return ERROR; 56 } 57 p = Space[h].cur; //p指向第一個結點 58 while (p) 59 { 60 Space[h].cur = Space[p].cur; //從數據鏈表首結點開始刪除 61 Free_SL(p); 62 p = Space[h].cur; 63 } 64 65 return OK; 66 } 67 68 void DestroyList_SL(SLinkList * h) 69 { 70 ClearList_SL(*h); 71 Free_SL(*h); //釋放頭結點 72 *h = 0; 73 } 74 75 Status ListEmpty_SL(SLinkList h) 76 { 77 if (h && !Space[h].cur) 78 { 79 return TRUE; 80 } 81 return FALSE; 82 } 83 84 int ListLength_SL(SLinkList h) 85 { 86 if (!h) 87 { 88 exit(OVERFLOW); 89 } 90 91 int count, p; 92 count = 0; 93 p = Space[h].cur; 94 while (p) 95 { 96 count++; 97 p = Space[p].cur; 98 } 99 return count; 100 } 101 102 Status GetElem_SL(SLinkList h, int i, ElementType * e) 103 { 104 //-2 去掉備用頭結點和數組溢出兩個 105 if (!h || i < 1 || i > MAXSIZE - 2) 106 { 107 return ERROR; 108 } 109 110 int count, p; 111 count = 0; 112 p = Space[h].cur; 113 while (p) 114 { 115 count++; //先++,從第一個邏輯位置開始,count很重要,尋找操作都需要count計數 116 if (count == i) 117 { 118 *e = Space[p].data; 119 return OK; 120 } 121 p = Space[p].cur; 122 } 123 return ERROR; 124 } 125 126 int LocateElem_SL(SLinkList h, ElementType e) 127 { 128 int k, count; 129 count = 1; 130 if (h && Space[h].cur) //不為空表 131 { 132 k = Space[h].cur; 133 while (k && Space[k].data != e) 134 { 135 count++; 136 k = Space[k].cur; 137 } 138 if (k) 139 { 140 return count; 141 } 142 } 143 return 0; 144 } 145 146 Status PriorElem_SL(SLinkList h, ElementType cur_e, ElementType * pre_e) 147 { 148 int p, q; 149 if (h) 150 { 151 p = Space[h].cur; 152 if (p && Space[p].data != cur_e) 153 { 154 q = Space[p].cur; 155 while (q && Space[q].data != cur_e) 156 { 157 p = q; //用p記住前驅 158 q = Space[q].cur; 159 } 160 if (q) 161 { 162 *pre_e = Space[q].data; 163 return OK; 164 } 165 } 166 } 167 return ERROR; 168 } 169 170 Status NextElem_SL(SLinkList h, ElementType cur_e, ElementType * next_e) 171 { 172 int p; 173 if (h) 174 { 175 p = Space[h].cur; 176 if (p && Space[p].data != cur_e) 177 { 178 p = Space[p].cur; 179 180 if (p && Space[p].cur) 181 { 182 p = Space[p].cur; 183 *next_e = Space[p].data; 184 return OK; 185 } 186 } 187 } 188 return ERROR; 189 } 190 191 Status ListInsert_SL(SLinkList h, int i, ElementType e) 192 { 193 if (!h) 194 { 195 return ERROR; 196 } 197 198 int count, k, p; 199 if (i > 0) // 200 { 201 count = 0; 202 k = h; 203 204 while (k && count < i - 1) //找到邏輯插入位置的前一個位置 205 { 206 count++; 207 k = Space[k].cur; 208 } 209 if (k) //找到第i-1個元素位置 210 { 211 p = Malloc_SL(); 212 if (!p) 213 { 214 return ERROR; 215 } 216 Space[p].data = e; 217 Space[p].cur = Space[k].cur; 218 Space[k].cur = p; 219 220 return OK; 221 } 222 } 223 return ERROR; 224 } 225 226 Status ListDelete_SL(SLinkList h, int i, ElementType * e) 227 { 228 if (!h) 229 { 230 return ERROR; 231 } 232 233 int count, k, p; 234 if (i > 0) 235 { 236 count = 0; 237 k = h; 238 while (k && count < i -1) //找到刪除位置的前一個位置 239 { 240 count++; 241 k = Space[k].cur; 242 } 243 244 if (k && Space[k].cur) //找到第i-1個元素卻不是尾結點 245 { 246 p = Space[k].cur; //p指向第i結點 247 *e = Space[p].data; 248 Space[k].cur = Space[p].cur; 249 Free_SL(p); 250 251 return OK; 252 } 253 } 254 return ERROR; 255 } 256 257 Status ListTraverse_SL(SLinkList h, void(Visit)(ElementType)) 258 { 259 if (!h) 260 { 261 return ERROR; 262 } 263 264 int p = Space[h].cur; 265 while (p) 266 { 267 Visit(Space[p].data); 268 p = Space[p].cur; 269 } 270 271 return OK; 272 }
Main函數
void PrintElem(ElementType e) { printf("%d ", e); } int main() { SLinkList h; //數據鏈表頭結點,全局 ElementType e; int i; printf("初始化靜態鏈表的備用空間Space...."); InitSpace_SL(); printf("\n"); PressEnter; printf("初始化靜態鏈表頭結點H,申請空間...."); InitList_SL(&h); printf("\n"); PressEnter; ListEmpty_SL(h) ? printf("h為空!\n") : printf("h不為空!\n"); printf("\n"); PressEnter; for (size_t j = 1; j < 6; ++j) { printf("在h第%d個位置插入%d\n", j, 2 * j); ListInsert_SL(h, j, 2 * j); printf("\n"); } printf("h中的元素為:h="); ListTraverse_SL(h, PrintElem); printf("\n"); PressEnter; printf("h的長度為%d\n", ListLength_SL(h)); printf("\n"); PressEnter; ListDelete_SL(h, 4, &e); printf("刪除h中第 4 個元素 %d,用Free_SL釋放空間....", e); printf("\n"); PressEnter; printf("刪除后h中的元素為:h="); ListTraverse_SL(h, PrintElem); printf("\n"); PressEnter; printf("元素8在h中的位序為%d\n",LocateElem_SL(h,8)); printf("\n"); printf("清空h前:"); ListEmpty_SL(h) ? printf("h為空!\n") : printf("h不為空!\n"); ClearList_SL(h); printf("清空h后:"); ListEmpty_SL(h) ? printf("h為空!\n") : printf("h不為空!\n"); printf("\n"); PressEnter; printf("銷毀h前:"); h ? printf("h存在!\n") : printf("h不存在!\n"); DestroyList_SL(&h); printf("銷毀h后:"); h ? printf("h存在!\n") : printf("h不存在!\n"); printf("\n"); PressEnter;
return 0; }
