首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

靜態鏈表(Static Linked List)資料結構原理與 C 語言完整實作

     編輯:關於C語言

什麼是靜態鏈表?

靜態鏈表以陣列模擬鏈結關係,每個元素包含 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_StaticList

int 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_StaticList

void 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

刪除 DeleteStaticList

void 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) 需遍歷指標
適用場景無動態分配環境、教學、嵌入式通用、現代語言標準庫

關鍵設計細節總結

  • 游標即索引:以整數下標取代指標,本質相同但無地址運算;
  • 備用鏈表頭在 Space[0]:統一管理所有閒置節點,分配/釋放均為 O(1);
  • 頭節點不存資料:cursor 指向第一個資料節點,空表時為 0;
  • 多表共存:單一陣列支援多條獨立鏈表,節點由備用鏈表動態分配給任一表;
  • 除錯利器:DisplaySpace 可視化整個陣列狀態,極利於理解空間佈局。

總結

靜態鏈表以陣列模擬指標結構,展現「游標=索引」的核心思想,是理解動態鏈表、記憶體池、檔案系統索引節點的最佳切入點。雖然現代開發較少直接使用,但其空間管理邏輯(Free List)廣泛應用於記憶體分配器、資料庫頁面管理、物件池等底層系統中。掌握其操作細節,能深化對指標本質與記憶體管理的認知。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved