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

C語言鏈表任意位置插入節點並同步寫入文件完整實現

     編輯:關於C語言

需求場景

單向鏈表存儲學生記錄(學號、姓名),支持:

  1. 指定學號後插入新節點
  2. 2. 操作後自動將整個鏈表覆寫回文件 `student.txt`

節點結構

typedef struct Student {
    char id[12];
    char name[20];
    struct Student *next;
} Student;

核心插入邏輯(圖解)

插入前:  head → [A] → [B] → [C] → NULL
                    ↑
                  目標節點 A (學號匹配)

插入後:  head → [A] → [NEW] → [B] → [C] → NULL
                    ↑       ↑
                  目標   新節點

完整實現代碼

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Student {
    char id[12];
    char name[20];
    struct Student *next;
} Student;

Student *insert_after_id(Student *head) {
    FILE *fp = fopen("student.txt", "wb");  // 覆寫模式
    if (!fp) { perror("文件打開失敗"); return head; }

    char target_id[12];
    printf("輸入要插入在其後的學號: "); scanf("%11s", target_id);

    Student *curr = head->next;  // 跳過哨兵頭
    Student *prev = head;

    // 1. 遍歷尋找目標節點,同步寫入已遍歷部分
    while (curr) {
        fwrite(curr, sizeof(Student), 1, fp);
        if (strcmp(curr->id, target_id) == 0) break;
        prev = curr;
        curr = curr->next;
    }

    if (!curr) {  // 未找到
        printf("未找到學號 %s\n", target_id);
        // 寫入剩餘節點
        while (curr) { fwrite(curr, sizeof(Student), 1, fp); curr = curr->next; }
        fclose(fp);
        return head;
    }

    // 2. 讀取新節點數據
    Student *new_node = malloc(sizeof(Student));
    printf("輸入新學號: "); scanf("%11s", new_node->id);
    printf("輸入新姓名: "); scanf("%19s", new_node->name);

    // 3. 鏈表插入操作
    new_node->next = curr->next;
    curr->next = new_node;

    // 4. 寫入新節點
    fwrite(new_node, sizeof(Student), 1, fp);

    // 5. 寫入剩餘節點
    curr = new_node->next;
    while (curr) {
        fwrite(curr, sizeof(Student), 1, fp);
        curr = curr->next;
    }

    fclose(fp);
    printf("插入成功並已同步到文件\n");
    return head;
}

關鍵步驟詳解

  1. 邊遍歷邊寫入:找到目標前,所有節點已寫入文件
  2. 斷鏈插入:
    new_node->next = curr->next;  // 1. 新節點指向原後繼
    curr->next = new_node;          // 2. 目標節點指向新節點
  3. 寫入新節點:`fwrite(new_node, ...)`
  4. 續寫剩餘:從 `new_node->next` 開始遍歷寫入

文件格式說明

  • 二進位模式 `wb`/`rb`,直接寫入結構體內存佈局
  • 要求結構體**無填充位差異**(同一編譯器、同一平台讀寫安全)
  • 跨平台/長期存儲建議改用文本格式(CSV/JSON)或序列化庫

完整測試主程式

Student *create_sample_list() {
    Student *head = calloc(1, sizeof(Student));
    Student *tail = head;
    const char *ids[] = {"1001", "1002", "1003"};
    const char *names[] = {"張三", "李四", "王五"};
    for (int i = 0; i < 3; i++) {
        Student *n = malloc(sizeof(Student));
        strcpy(n->id, ids[i]); strcpy(n->name, names[i]);
        n->next = NULL; tail->next = n; tail = n;
    }
    // 初始化文件
    FILE *fp = fopen("student.txt", "wb");
    for (Student *p = head->next; p; p = p->next) fwrite(p, sizeof(Student), 1, fp);
    fclose(fp);
    return head;
}

void print_list(Student *head) {
    for (Student *p = head->next; p; p = p->next)
        printf("[%s] %s\n", p->id, p->name);
}

int main() {
    Student *head = create_sample_list();
    printf("原始鏈表:\n"); print_list(head);
    head = insert_after_id(head);
    printf("插入後鏈表:\n"); print_list(head);
    return 0;
}

常見錯誤與修正

| 錯誤 | 後果 | 修正 | |------|------|------| | 插入順序顛倒:`curr->next = new_node; new_node->next = curr->next;` | 形成自環,丟失原後繼 | 嚴格遵循:先 `new_node->next = curr->next;` 再 `curr->next = new_node;` | | 文件模式用 `ab`(追加) | 重複插入導致文件越來越大 | 用 `wb` 覆寫整個鏈表 | | 未檢查 `malloc` 返回 | OOM 時段錯誤 | 插入前判空 | | 忘記寫入剩餘節點 | 文件數據截斷 | 插入後務必遍歷寫入 `new_node->next` 之後所有節點 |

總結

鏈表任意位置插入的核心是指針重連順序,配合邊遍歷邊持久化即可實現文件同步。關鍵模式:

// 1. 斷鏈插入(標準三步)
new->next = target->next;
target->next = new;

// 2. 持久化同步
fwrite(已遍歷部分);
fwrite(new_node);
fwrite(剩餘部分);

掌握此模式,可擴展至刪除、修改、排序等所有鏈表更新操作的文件同步場景。

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