靜態鏈表以陣列模擬鏈結關係,每個元素包含 data(資料)與 cursor(游標/下一個元素的陣列索引)。不使用動態記憶體分配,所有節點預先在陣列中分配,透過「備用鏈表」管理閒置空間。適用於不支援動態分配的環境(如早期嵌入式系統、FORTRAN、教學示範指標邏輯)。
#define MAXSIZE 20
typedef struct {
int data;
int cursor; // 0 表示空/結束,1~MAXSIZE-1 為有效索引
} Node, StaticList[MAXSIZE];
Space[0].cursor 作為備用鏈表頭指標,指向第一個可用節點;各鏈表頭節點索引由 InitialStaticList 分配獲得,其 cursor 指向第一個資料節點或 0(空表)。
void InitialSpace(StaticList Space) {
for (int i=0; i
Malloc_StaticListint Malloc_StaticList(StaticList Space) {
int i = Space[0].cursor;
if (i) { Space[0].cursor = Space[i].cursor; return i; }
else { printf("Space Full\n"); exit(1); }
}
Free_StaticListvoid Free_StaticList(StaticList Space, int index) {
Space[index].data = 0;
Space[index].cursor = Space[0].cursor;
Space[0].cursor = index; // 回收到備用鏈表頭部
}
int InitialStaticList(StaticList Space) { // 分配頭節點
int i = Malloc_StaticList(Space);
Space[i].cursor = 0; return i;
}
void ClearStaticList(StaticList Space, int n_List) {
int cur = Space[n_List].cursor, tmp;
while (cur) { tmp = Space[cur].cursor; Free_StaticList(Space, cur); cur = tmp; }
Space[n_List].cursor = 0;
}
bool StaticListEmpty(StaticList Space, int n_List) { return Space[n_List].cursor == 0; }
int StaticListLength(StaticList Space, int n_List) {
int cnt=0, cur=Space[n_List].cursor;
while (cur) { cnt++; cur = Space[cur].cursor; } return cnt;
}
InsertStaticList(Space, list, pos, e)在第 pos 個位置(1-based)插入 e,需遍歷至前驅節點修改游標。
void InsertStaticList(StaticList Space, int n_List, int pos, int e) {
int len = StaticListLength(Space, n_List);
if (pos<1 || pos>len+1) { printf("Pos Error\n"); exit(1); }
int new_i = Malloc_StaticList(Space);
Space[new_i].data = e;
int pre = n_List;
for (int i=1; i
DeleteStaticListvoid DeleteStaticList(StaticList Space, int n_List, int pos) {
int len = StaticListLength(Space, n_List);
if (pos<1 || pos>len) { printf("Pos Error\n"); return; }
int pre = n_List;
for (int i=1; i
int GetStaticListElement(StaticList Space, int n_List, int pos) {
int cur = n_List, cnt=0;
while (Space[cur].cursor && cnt
同一 Space 陣列可同時容納多條鏈表(list1、list2、list3),透過不同頭節點索引區分。DisplaySpace 印出全陣列 cursor、data、索引三行,便於除錯觀察空間分配狀態。
int main() {
StaticList space;
// 初始化
InitialSpace(space);
int list1 = InitialStaticList(space);
int list2 = InitialStaticList(space);
int list3 = InitialStaticList(space);
// 建立測試資料
CreateStaticList(space, list3, 5); // 互動輸入 5 個元素
CreateStaticList(space, list2, 25); // 觸發空間不足
InsertStaticList(space, list3, 4, 666);
GetStaticListElement(space, list3, 3);
LocateStaticList(space, list3, 4);
NextElement_SL(space, list3, 9);
PriorElement_SL(space, list3, 3);
DeleteStaticList(space, list3, 5);
ClearStaticList(space, list3);
return 0;
}
| 維度 | 靜態鏈表 | 動態鏈表 |
|---|---|---|
| 記憶體管理 | 編譯期固定陣列,無 malloc/free | 執行期動態申請釋放 |
| 容量擴充 | 固定 MAXSIZE,滿則失敗 | 理論無上限(受限於記憶體) |
| 插入刪除 | O(1) 修改游標,無移動元素 | O(1) 修改指標,同樣高效 |
| 隨機存取 | O(n) 需遍歷游標 | O(n) 需遍歷指標 |
| 適用場景 | 無動態分配環境、教學、嵌入式 | 通用、現代語言標準庫 |
cursor 指向第一個資料節點,空表時為 0;DisplaySpace 可視化整個陣列狀態,極利於理解空間佈局。靜態鏈表以陣列模擬指標結構,展現「游標=索引」的核心思想,是理解動態鏈表、記憶體池、檔案系統索引節點的最佳切入點。雖然現代開發較少直接使用,但其空間管理邏輯(Free List)廣泛應用於記憶體分配器、資料庫頁面管理、物件池等底層系統中。掌握其操作細節,能深化對指標本質與記憶體管理的認知。