1. 程式人生 > >連結串列的插入和刪除操作詳解(C語言實現+詳解註釋)

連結串列的插入和刪除操作詳解(C語言實現+詳解註釋)

連結串列的基本操作中,連結串列結點的插入和刪除相對比較複雜,需根據結點插入位置的不同,使用合理的方法在不破壞原連結串列結構的前提下將其插入到連結串列中。

本節將詳解介紹這兩種操作的具體實現方法,讀者只需牢記實現步驟,即可輕鬆解決這兩大難點。

連結串列中插入結點

連結串列中插入結點,根據插入位置的不同,可分為以下 3 種情況:
  1. 插入到連結串列的首部,也就是頭結點和首元結點中間;
  2. 插入到連結串列中間的某個位置;
  3. 插入到連結串列最末端;

圖 1 連結串列中插入結點5
雖然插入位置有區別,都使用相同的插入手法。分為 2 步,如圖 1 所示:
  • 將新結點的 next 指標指向插入位置後的結點;
  • 將插入位置前的結點的 next 指標指向插入結點;

提示:在做插入操作時,首先要找到插入位置的上一個結點,拿圖 1 來說,也就是找到結點 1,相應的結點 2 可通過結點 1 的 next 指標表示。這樣,先進行步驟 1,後進行步驟 2,實現過程中不需要新增其他輔助指標。

實現程式碼:
link * insertElem(link * p,int elem,int add){
    link * temp=p;//建立臨時結點temp
    //首先找到要插入位置的上一個結點
    for (int i=1; i<add; i++) {
        if (temp==NULL) {
            printf("插入位置無效\n");
            return p;
        }
        temp=temp->next;
    }    
    //建立插入結點c
    link * c=(link*)malloc(sizeof(link));
    c->elem=elem;
    //向連結串列中插入結點
    c->next=temp->next;
    temp->next=c;
    return  p;
}
注意,首先要保證插入位置的可行性,例如圖 1 中,原本只有 5 個結點,因此插入位置可選擇的範圍為:1-6,如果超過 6,由於操作本身無意義,程式會提示插入位置無效。

連結串列中刪除節點

當需要從連結串列中刪除某個結點時,需要進行 2 步操作:
  • 將結點從連結串列中摘下來;
  • 手動釋放掉結點,回收被結點佔用的記憶體空間;
使用 malloc 函式申請的空間,一定要注意手動 free 掉。否則在程式執行的整個過程中,申請的記憶體空間不會自己釋放(只有當整個程式執行完了以後,這塊記憶體才會被回收),造成記憶體洩漏,別把它當成是小問題。
實現程式碼:
link * delElem(link * p,int add){
    link * temp=p;
    //temp指向被刪除結點的上一個結點
    for (int i=1; i<add; i++) {
        temp=temp->next;
    }
    link * del=temp->next;//單獨設定一個指標指向被刪除結點,以防丟失
    temp->next=temp->next->next;//刪除某個結點的方法就是更改前一個結點的指標域
    free(del);//手動釋放該結點,防止記憶體洩漏
    return p;
}

完整程式碼

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

typedef struct Link{
    int  elem;
    struct Link *next;
}link;
link * initLink();
//連結串列插入的函式,p是連結串列,elem是插入的結點的資料域,add是插入的位置
link * insertElem(link * p,int elem,int add);
//刪除結點的函式,p代表操作連結串列,add代表刪除節點的位置
link * delElem(link * p,int add);
void display(link *p);

int main() {
    //初始化連結串列(1,2,3,4)
    printf("初始化連結串列為:\n");
    link *p=initLink();
    display(p);
   
    printf("在第4的位置插入元素5:\n");
    p=insertElem(p, 5, 4);
    display(p);
   
    printf("刪除元素3:\n");
    p=delElem(p, 3);
    display(p);
    return 0;
}

link * initLink(){
    link * p=(link*)malloc(sizeof(link));//建立一個頭結點
    link * temp=p;//宣告一個指標指向頭結點,用於遍歷連結串列
    //生成連結串列
    for (int i=1; i<5; i++) {
        link *a=(link*)malloc(sizeof(link));
        a->elem=i;
        a->next=NULL;
        temp->next=a;
        temp=temp->next;
    }
    return p;
}
link * insertElem(link * p,int elem,int add){
    link * temp=p;//建立臨時結點temp
    //首先找到要插入位置的上一個結點
    for (int i=1; i<add; i++) {
        if (temp==NULL) {
            printf("插入位置無效\n");
            return p;
        }
        temp=temp->next;
    }
    //建立插入結點c
    link * c=(link*)malloc(sizeof(link));
    c->elem=elem;
    //向連結串列中插入結點
    c->next=temp->next;
    temp->next=c;
    return  p;
}

link * delElem(link * p,int add){
    link * temp=p;
    //遍歷到被刪除結點的上一個結點
    for (int i=1; i<add; i++) {
        temp=temp->next;
    }
    link * del=temp->next;//單獨設定一個指標指向被刪除結點,以防丟失
    temp->next=temp->next->next;//刪除某個結點的方法就是更改前一個結點的指標域
    free(del);//手動釋放該結點,防止記憶體洩漏
    return p;
}
void display(link *p){
    link* temp=p;//將temp指標重新指向頭結點
    //只要temp指標指向的結點的next不是Null,就執行輸出語句。
    while (temp->next) {
        temp=temp->next;
        printf("%d",temp->elem);
    }
    printf("\n");
}
執行結果:
初始化連結串列為:
1234
在第4的位置插入元素5:
12354
刪除元素3:
1254