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

C語言單鏈表綜合實戰:創建、查找、插入、刪除、遍歷與菜單驅動完整實現

     編輯:關於C語言

專案概覽

本文展示一個完整的單鏈表管理系統,包含節點創建、關鍵字查找(返回節點/前驅節點)、指定位置後插入、關鍵字刪除、遍歷打印、文本菜單交互,代碼結構清晰,適合作為數據結構教學參考與基礎組件庫。

數據結構定義


#define N 10
typedef struct node {
    char name[20];
    struct node *link;
} stud;
  • 柔性設計:name 固定長度,實際可改為動態分配。
  • link 自引用指標構成鏈表骨架。

核心操作函數解析

1. 創建鏈表 creat(n) — 尾插法帶頭節點


stud *creat(int n) {
    stud *h, *p, *s;
    if ((h = malloc(sizeof(stud))) == NULL) exit(0);  // 頭節點
    h->name[0] = '\0'; h->link = NULL;
    p = h;
    for (int i = 0; i < n; i++) {
        if ((s = malloc(sizeof(stud))) == NULL) exit(0);
        p->link = s;
        printf("請輸入第%d個人的姓名: ", i+1);
        scanf("%s", s->name);
        s->link = NULL;
        p = s;
    }
    return h;  // 返回頭節點
}
  • 頭節點不存儲數據,簡化插入刪除邊界條件(無需特判首節點)。
  • 輸入 n 個節點,尾指針 p 移動,O(n) 構建。

2. 查找節點 search(h, x) — 返回目標節點指標


stud *search(stud *h, char *x) {
    stud *p = h->link;
    while (p) {
        if (strcmp(p->name, x) == 0) return p;
        p = p->link;
    }
    printf("沒有查找到該數據!\n");
    return NULL;  // 隱式返回
}

3. 查找前驅節點 search2(h, x) — 為刪除服務


stud *search2(stud *h, char *x) {
    stud *p = h->link, *s = h;
    while (p) {
        if (strcmp(p->name, x) == 0) return s;
        p = p->link; s = s->link;
    }
    printf("沒有查找到該數據!\n");
    return NULL;
}
  • 同步維護 s 指向 p 的前驅,刪除時直接 s->link = p->link。

4. 插入節點 insert(p) — 在節點 p 後插入


void insert(stud *p) {
    stud *s = malloc(sizeof(stud));
    if (!s) exit(0);
    printf("請輸入你要插入的人的姓名: ");
    scanf("%s", s->name);
    s->link = p->link;
    p->link = s;
}
  • 經典「新節點 link 指向原後繼,前驅 link 指向新節點」兩步驟,順序不可反。

5. 刪除節點 del(x, y) — 刪除 y,x 為前驅


void del(stud *x, stud *y) {
    stud *s = y;
    x->link = y->link;
    free(s);
}

6. 遍歷打印 print(h)


void print(stud *h) {
    stud *p = h->link;
    printf("數據信息為:\n");
    while (p) {
        printf("%s ", p->name);
        p = p->link;
    }
}

菜單驅動主程序


void menu() {
    clrscr();
    printf("\t\t\t單鏈表C語言實現實例\n");
    printf("\t\t|--------------------------|\n");
    printf("\t\t| [1] 建立新表             |\n");
    printf("\t\t| [2] 查找數據             |\n");
    printf("\t\t| [3] 插入數據             |\n");
    printf("\t\t| [4] 刪除數據             |\n");
    printf("\t\t| [5] 打印數據             |\n");
    printf("\t\t| [6] 退出                 |\n");
    printf("\t\t| 如未建立新表,請先建立! |\n");
    printf("\t\t|--------------------------|\n");
    printf("\t\t 請輸入你的選項(1-6): ");
}

int main() {
    int choose;
    stud *head = NULL, *searchpoint, *forepoint;
    char fullname[20];
    while (1) {
        menu();
        scanf("%d", &choose);
        switch (choose) {
            case 1: head = creat(N); break;
            case 2:
                printf("輸入查找姓名: "); scanf("%s", fullname);
                searchpoint = search(head, fullname);
                if (searchpoint) printf("找到: %s\n", searchpoint->name);
                getchar(); getchar(); break;
            case 3:
                printf("輸入插入位置後的姓名: "); scanf("%s", fullname);
                searchpoint = search(head, fullname);
                if (searchpoint) { insert(searchpoint); print(head); }
                getchar(); getchar(); break;
            case 4:
                print(head);
                printf("輸入刪除姓名: "); scanf("%s", fullname);
                searchpoint = search(head, fullname);
                forepoint = search2(head, fullname);
                if (searchpoint && forepoint) del(forepoint, searchpoint);
                break;
            case 5: print(head); getchar(); getchar(); break;
            case 6: exit(0);
            default: printf("非法輸入!"); getchar(); break;
        }
    }
}

代碼審計與改進建議

擴展方向:雙向鏈表與循環鏈表

  • 雙向鏈表:節點增加 prev 指標,支援雙向遍歷、O(1) 刪除給定節點(無需前驅查找)。
  • 循環鏈表:尾節點 link 指向頭節點,適用於循環調度、约瑟夫環問題。
  • 本文代碼邏輯可通過修改節點結構與操作函數平滑遷移至上述變體。

總結

本實現完整覆蓋了單鏈表創建、查找、插入、刪除、遍歷五大核心操作,採用帶頭節點設計簡化邊界處理,配合菜單驅動交互構成完整教學級應用。代碼雖存在輸入安全、錯誤處理、資源管理等工程化不足,但邏輯清晰、結構標準,是理解鏈表指針操作本質的優秀範本。工程落地時請依照審計建議加固。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題風險改進
scanf("%s") 無長度限制緩衝區溢出scanf("%19s", name) 或 fgets
malloc 失敗直接 exit(0)資源洩漏、無優雅降級返回錯誤碼,上層釋放已分配內存後退出
查找失敗返回 NULL 但調用者未檢查空指標解引用崩潰所有調用處必須判空
菜單輸入非數字導致死循環scanf 留殘留字符檢查 scanf 返回值,清理輸入緩衝區
getchar(); getchar(); 吸收換行符不可靠,輸入含空格失效用 while(getchar()!='\n'); 清行
全局 N=10 固定容量擴展性差動態分配,無人為上限
無鏈表銷毀函數退出時內存洩漏實現 destroy(head) 遞歸/迭代 free