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

鏈表數據結構全景指南:單鏈表創建、插入、刪除與綜合實例

     編輯:關於C語言

為什麼需要鏈表?

數組雖然訪問快(O(1)),但大小固定、插入刪除需移動元素(O(n))、易造成空間浪費或不足。鏈表通過動態內存分配,按需申請釋放,完美解決上述痛點:

  • 空間靈活:無需預分配,用多少申請多少
  • 插刪高效:僅修改指針,無需移動數據
  • 結構多樣:單向、雙向、循環多種變體適應不同場景

單鏈表核心結構定義

struct node {
    int num;              // 數據域:此處存整型
    struct node *next;    // 指針域:指向同類型下一節點
};

注意:結構體內使用未完全定義的類型指針,這是 C 語言允許的特例(遞歸定義)。

單鏈表創建:尾插法完整實現

struct node *creat(struct node *head) {
    struct node *p1, *p2;
    p1 = p2 = (struct node *)malloc(sizeof(struct node));
    scanf("%d", &p1->num);
    p1->next = NULL;
    
    while (p1->num > 0) {  // 輸入正整數,-999 結束
        if (head == NULL)
            head = p1;           // 空表,接入表頭
        else
            p2->next = p1;       // 非空表,接到表尾
        p2 = p1;
        p1 = (struct node *)malloc(sizeof(struct node));
        scanf("%d", &p1->num);
    }
    return head;
}

單鏈表遍歷輸出

void print(struct node *head) {
    struct node *temp = head;
    while (temp != NULL) {
        printf("%6d", temp->num);
        temp = temp->next;
    }
}

節點刪除:三種情況統一處理

刪除節點可能發生在表頭、表中、表尾。關鍵是保持前驅節點指向後繼:

struct node *delet(struct node *head, char *pstr) {
    struct node *temp = head, *p;
    if (head == NULL) {
        printf("鏈表為空!\n");
        return head;
    }
    while (strcmp(temp->str, pstr) != 0 && temp->next != NULL) {
        p = temp;
        temp = temp->next;
    }
    if (strcmp(temp->str, pstr) == 0) {
        if (temp == head) {          // 刪除表頭
            head = head->next;
            free(temp);
        } else {                     // 刪除表中/表尾
            p->next = temp->next;
            free(temp);
        }
    } else {
        printf("未找到目標節點!\n");
    }
    return head;  // 返回新頭指針,防止表頭刪除導致頭指針失效
}

節點插入:按學號有序插入

插入位置同樣分表頭、表中、表尾三種:

struct node *insert(struct node *head, char *pstr, int n) {
    struct node *p1 = (struct node *)malloc(sizeof(struct node));
    strcpy(p1->str, pstr);
    p1->num = n;
    
    struct node *p2 = head, *p3;
    if (head == NULL) {              // 空表
        head = p1;
        p1->next = NULL;
    } else {
        while (n > p2->num && p2->next != NULL) {
            p3 = p2;
            p2 = p2->next;
        }
        if (n <= p2->num) {          // 找到插入位置
            if (head == p2) {        // 插入表頭
                head = p1;
                p1->next = p2;
            } else {                 // 插入表中
                p3->next = p1;
                p1->next = p2;
            }
        } else {                     // 插入表尾
            p2->next = p1;
            p1->next = NULL;
        }
    }
    return head;
}

綜合實例:學生信息管理系統

完整程序包含:創建有序鏈表 → 輸出 → 插入新節點 → 輸出 → 刪除指定節點 → 輸出。核心模塊:

  • creat():輸入學號、姓名,按學號遞增建表,空姓名結束
  • insert():按學號有序插入
  • delet():按姓名刪除
  • print():格式化輸出所有節點

關鍵工程經驗總結

  1. 頭指針管理:所有修改表頭的操作(插入/刪除表頭)必須返回新頭指針,調用端需接收更新。
  2. 內存安全:malloc 必檢查,free 後指針置 NULL,防止野指針/二次釋放。
  3. 邊界測試:空表、單節點、頭尾操作、重複鍵值、未找到目標等場景需全覆蓋測試。
  4. 輸入健壯性:使用 fgets + sscanf 替代 scanf,處理換行符、緩衝區溢出。

擴展方向

掌握單鏈表後,可進階學習:雙向鏈表(O(1) 刪除已知節點)、循環鏈表(輪詢調度)、跳表(O(log n) 查找)、鏈式隊列/棧(ADT 實現)。鏈表是理解圖、樹等複雜結構的基石,建議反復練習手寫核心操作。

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