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

C語言鏈表完整實現:增刪改查與菜單驅動演示

     編輯:關於C語言

C語言鏈表完整實現:增刪改查與菜單驅動演示

鏈表是C語言中實現動態數據結構的核心基礎。本文提供一個完整的單向鏈表教學級實現,包含節點定義、創建、遍歷、查找、修改、刪除、尾部插入等核心操作,並構建了交互式菜單系統演示所有功能。代碼雖屬初學者作品,但邏輯完整,極適合理解指針操作與動態內存管理。

數據結構定義

struct Student {
    int a;                    // 數據域1
    int b;                    // 數據域2
    struct Student* next;     // 指針域
};

struct Student* head = NULL;  // 全局頭指針
int nodeCount = 0;            // 節點計數器

核心功能函數詳細解析

1. 創建鏈表(頭插法/尾插法混合)

void AddNodes() {
    printf("請輸入要存儲的兩個整數(輸入0 0結束)\n");
    struct Student *p1, *p2;
    p1 = p2 = (struct Student*)malloc(sizeof(struct Student));
    head->next = p1;
    scanf("%d %d", &p2->a, &p2->b);
    
    while (p2->a != 0) {  // 以a==0作為結束標記
        nodeCount++;
        p1->next = p2;
        p1 = p2;
        p2 = (struct Student*)malloc(sizeof(struct Student));
        scanf("%d %d", &p2->a, &p2->b);
    }
    p1->next = NULL;  // 尾節點指向NULL
}

注意:原代碼使用 scanf_s(MSVC專用),本文統一改為標準 scanf;結束條件 p2->a != NULL 邏輯有誤,已修正為 != 0。

2. 遍歷打印鏈表

void PrintList(struct Student* head) {
    if (head->next == NULL) {
        printf("鏈表為空!\n");
        return;
    }
    struct Student* p = head->next;
    while (p != NULL) {
        printf("%d\t%d\n", p->a, p->b);
        p = p->next;
    }
}

3. 按位置查找節點

void FindNode() {
    if (head->next == NULL) { printf("鏈表為空!\n"); return; }
    int pos; printf("請輸入查找位置(1-%d): ", nodeCount); scanf("%d", &pos);
    if (pos < 1 || pos > nodeCount) { printf("位置無效!\n"); return; }
    
    struct Student* p = head->next;
    for (int i = 1; i < pos; i++) p = p->next;
    printf("第%d個節點: %d\t%d\n", pos, p->a, p->b);
}

4. 按位置修改節點數據

void ModifyNode() {
    if (head->next == NULL) { printf("鏈表為空!\n"); return; }
    int pos; printf("請輸入修改位置(1-%d): ", nodeCount); scanf("%d", &pos);
    if (pos < 1 || pos > nodeCount) { printf("位置無效!\n"); return; }
    
    struct Student* p = head->next;
    for (int i = 1; i < pos; i++) p = p->next;
    printf("請輸入新的兩個整數: "); scanf("%d %d", &p->a, &p->b);
}

5. 按位置刪除節點

void DeleteNode() {
    if (head->next == NULL) { printf("鏈表為空!\n"); return; }
    int pos; printf("請輸入刪除位置(1-%d): ", nodeCount); scanf("%d", &pos);
    if (pos < 1 || pos > nodeCount) { printf("位置無效!\n"); return; }
    
    struct Student* p = head;  // 從頭節點開始,方便找到前驅
    for (int i = 1; i < pos; i++) p = p->next;
    struct Student* del = p->next;
    p->next = del->next;
    free(del);
    nodeCount--;
}

6. 尾部追加節點

void AppendNodes() {
    if (head->next == NULL) { printf("鏈表為空!\n"); return; }
    // 先遍歷到尾部
    struct Student* p = head->next;
    while (p->next != NULL) p = p->next;
    
    printf("請輸入要追加的數據(輸入0 0結束)\n");
    struct Student *p2, *p3;
    p2 = p3 = (struct Student*)malloc(sizeof(struct Student));
    p->next = p2;
    scanf("%d %d", &p3->a, &p3->b);
    while (p3->a != 0) {
        nodeCount++;
        p2->next = p3;
        p2 = p3;
        p3 = (struct Student*)malloc(sizeof(struct Student));
        scanf("%d %d", &p3->a, &p3->b);
    }
    p2->next = NULL;
}

主程序:交互式菜單系統

int main() {
    head = (struct Student*)malloc(sizeof(struct Student));
    head->next = NULL;
    nodeCount = 0;

    printf("=== 單向鏈表操作演示系統 ===\n");
    printf("1. 創建鏈表  2. 遍歷顯示  3. 尾部追加\n");
    printf("4. 刪除節點  5. 修改節點  6. 查找節點\n");
    printf("0. 退出程序\n");

    int choice;
    while (1) {
        printf("\n請選擇功能(0-6): ");
        scanf("%d", &choice);
        switch (choice) {
            case 0: printf("謝謝使用!\n"); return 0;
            case 1: AddNodes(); break;
            case 2: PrintList(head); break;
            case 3: AppendNodes(); break;
            case 4: DeleteNode(); break;
            case 5: ModifyNode(); break;
            case 6: FindNode(); break;
            default: printf("無效選項!\n");
        }
    }
}

關鍵技術點總結

  • 頭節點技巧:引入不存數據的頭節點,統一了空表/非空表的邊界處理
  • 雙指針協作:p1跟蹤當前節點,p2預分配下一節點,實現鏈式構建
  • 內存管理:每個 malloc 必須對應 free,刪除操作演示了正確釋放
  • 邊界檢查:所有操作均檢查位置合法性,防止指針越界

常見錯誤與改進建議

  1. scanf_s 移植性:改用標準 scanf 或封裝跨平台輸入函數
  2. 結束標記衝突:以數據值 0 作為結束標記會無法存儲合法的 0 值,建議改用單獨的命令字符
  3. 內存洩漏風險:創建/追加過程中若輸入異常中斷,已分配內存未釋放
  4. 全局變量:頭指針和計數器為全局,多鏈表場景下應封裝為結構體

總結

本文通過完整可運行的代碼,演示了單向鏈表的全生命周期操作。雖代碼風格屬教學初期作品,但涵蓋了指針操作、動態內存、鏈表遍歷修改等C語言核心難點。建議初學者在理解基礎上,嘗試重構為雙向鏈表、帶哨兵節點鏈表或泛型鏈表,進一步鞏固數據結構功底。

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