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

C語言實現雙向循環鏈表節點刪除操作詳解

     編輯:關於C語言

雙向循環鏈表刪除節點的核心邏輯

在雙向循環鏈表中刪除節點,本質上是插入操作的逆過程。假設有三個連續節點 s、p、q,要刪除中間節點 p,只需將 s 的右鏈域指向 q,同時將 q 的左鏈域指向 s,最後釋放 p 佔用的內存即可完成刪除。這一操作保持了鏈表的雙向循環結構完整性。

完整代碼實現示例

下方展示一個基於雙向循環鏈表的學生信息管理系統,包含創建、查找、打印、刪除等核心功能:

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

#define N 10

typedef struct node {
    char name[20];
    struct node *llink, *rlink;
} stud;

/* 創建帶頭節點的雙向循環鏈表 */
stud *creat(int n) {
    stud *p, *h, *s;
    int i;
    if ((h = (stud *)malloc(sizeof(stud))) == NULL) {
        printf("無法分配內存空間!\n");
        exit(0);
    }
    h->name[0] = '\0';
    h->llink = NULL;
    h->rlink = NULL;
    p = h;
    for (i = 0; i < n; i++) {
        if ((s = (stud *)malloc(sizeof(stud))) == NULL) {
            printf("無法分配內存空間!\n");
            exit(0);
        }
        p->rlink = s;
        printf("請輸入第 %d 個人的姓名:", i + 1);
        scanf("%s", s->name);
        s->llink = p;
        s->rlink = NULL;
        p = s;
    }
    h->llink = s;
    p->rlink = h;
    return h;
}

/* 按姓名查找節點 */
stud *search(stud *h, char *x) {
    stud *p;
    char *y;
    p = h->rlink;
    while (p != h) {
        y = p->name;
        if (strcmp(y, x) == 0)
            return p;
        else
            p = p->rlink;
    }
    printf("未查找到該數據!\n");
    return NULL;
}

/* 打印鏈表所有節點 */
void print(stud *h) {
    stud *p = h->rlink;
    printf("數據信息為:\n");
    while (p != h) {
        printf("%s ", p->name);
        p = p->rlink;
    }
    printf("\n");
}

/* 刪除指定節點 */
void del(stud *p) {
    (p->rlink)->llink = p->llink;
    (p->llink)->rlink = p->rlink;
    free(p);
}

int main() {
    int number = N;
    char studname[20];
    stud *head, *searchpoint;
    
    head = creat(number);
    print(head);
    
    printf("請輸入你要查找的人的姓名:");
    scanf("%s", studname);
    searchpoint = search(head, studname);
    
    if (searchpoint) {
        printf("你所要查找的人的姓名是:%s\n", searchpoint->name);
        del(searchpoint);
        print(head);
    }
    return 0;
}

關鍵點解析

  • 頭節點初始化:頭節點不存儲有效數據,name[0]='\0' 標記為空,雙向指針初始化為 NULL。
  • 循環閉合:創建完成後,頭節點的 llink 指向尾節點,尾節點的 rlink 指向頭節點,形成循環。
  • 刪除操作:del() 函數通過修改前驅、後繼節點的指針域實現節點剔除,最後 free(p) 釋放內存,防止洩漏。
  • 查找邏輯:從頭節點的 rlink 開始遍歷,遇到頭節點則結束,未找到時返回 NULL 並提示。

常見問題與注意事項

實際開發中需注意:刪除節點前務必確認節點存在(查找函數返回非 NULL);釋放內存後將指針置 NULL 避免野指針;輸入處理建議加入緩衝區溢出保護(如使用 fgets 替代 scanf)。雙向循環鏈表雖操作稍繁瑣,但支持雙向遍歷、O(1) 刪除已知節點,適合頻繁增刪場景。

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