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

C語言單向鏈表插入操作:後插演算法與完整程式碼實作

     編輯:關於C語言

單向鏈表插入原理:後插法

已知連續兩節點 p(前驅)、q(後繼),在兩者間插入新節點 s:

  1. 配置 s 記憶體並賦值
  2. s->link = q(或 p->link)
  3. p->link = s

順序關鍵:先連 s->link,再改 p->link,否則會丟失 q 位址。

完整程式碼實作

結構定義


typedef struct node {
    char name[20];
    struct node *link;
} stud;

建立鏈表 creat()


stud *creat(int n) {
    stud *p, *h, *s;
    int i;
    if ((h = (stud *)malloc(sizeof(stud))) == NULL) {
        printf("記憶體配置失敗!");
        exit(0);
    }
    h->name[0] = '\0';
    h->link = NULL;
    p = h;
    for (i = 0; i < n; i++) {
        if ((s = (stud *)malloc(sizeof(stud))) == NULL) {
            printf("記憶體配置失敗!");
            exit(0);
        }
        p->link = s;
        printf("請輸入第%d個人的姓名: ", i+1);
        scanf("%s", s->name);
        s->link = NULL;
        p = s;
    }
    return h;
}

查找節點 search()


stud *search(stud *h, char *x) {
    stud *p;
    char *y;
    p = h->link;
    while (p != NULL) {
        y = p->name;
        if (strcmp(y, x) == 0)
            return p;
        else
            p = p->link;
    }
    if (p == NULL)
        printf("沒有查找到該資料!\n");
    return NULL;
}

後插函數 insert()


void insert(stud *p) {
    char stuname[20];
    stud *s;
    if ((s = (stud *)malloc(sizeof(stud))) == NULL) {
        printf("記憶體配置失敗!");
        exit(0);
    }
    printf("請輸入你要插入的人的姓名: ");
    scanf("%s", stuname);
    strcpy(s->name, stuname);  // 複製姓名到新節點

    s->link = p->link;  // 1. 新節點指向原後繼
    p->link = s;        // 2. 前驅指向新節點
}

主程式


#include 
#include 
#include 

#define N 10

typedef struct node {
    char name[20];
    struct node *link;
} stud;

stud *creat(int n);
stud *search(stud *h, char *x);
void insert(stud *p);

main() {
    int number = N;
    char fullname[20];
    stud *head, *searchpoint;

    head = creat(number);
    printf("請輸入你要查找的人的姓名: ");
    scanf("%s", fullname);
    searchpoint = search(head, fullname);
    if (searchpoint)
        insert(searchpoint);
}

插入操作記憶體圖解


// 插入前:p → q
p → [name="Alice"][link=q]
q → [name="Bob"][link=...]

// 步驟 1:s->link = p->link (即 q)
s → [name="New"][link=q]

// 步驟 2:p->link = s
p → [name="Alice"][link=s]
s → [name="New"][link=q]

// 結果:p → s → q

關鍵技術點

  1. malloc 檢查:每次配置必判斷 NULL
  2. strcpy 複製字串:s->name 為陣列,不可直接指派指標,需 strcpy
  3. 指標重連順序:先建立新連結(s->link),再斷舊連結(p->link)
  4. 查找返回節點指標:search 返回 stud*,insert 直接操作該節點
  5. 頭節點不存資料:h->name[0]='\0',資料從 h->link 開始

插入位置變體

常見錯誤

  1. 順序顛倒:p->link = s; s->link = p->link; → 丟失原後繼
  2. 未複製字串:s->name = stuname; → 指向區域變數,函數返回失效
  3. 忘記設 s->link = NULL(尾插時)
  4. 查找失敗未檢查:insert(NULL) 導致崩潰

複雜度分析

  • 查找:O(n)
  • 插入操作本身:O(1)
  • 總計:O(n)(以查找為主)

若頻繁插入,考慮雙向鏈表、跳表或平衡樹優化查找。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
類型描述關鍵差異
頭插插入頭節點之後s->link = h->link; h->link = s;
後插指定節點之後(本例)需先查找前驅節點
尾插插入鏈表末尾需遍歷至尾節點或維護尾指標
有序插入依值大小插入保持有序查找插入位置 + 後插
前插指定節點之前單向鏈表需從頭找前驅,雙向鏈表 O(1)