詳解雙向鍊錶的基本操作 C語言

2021-10-05 01:24:16 字數 4281 閱讀 8247

上一節學習了單向煉表單鍊錶詳解。今天學習雙鏈表。學習之前先對單向鍊錶和雙向鍊錶做個回顧。

單向鍊錶特點

1.我們可以輕鬆的到達下乙個節點, 但是回到前乙個節點是很難的.

2.只能從頭遍歷到尾或者從尾遍歷到頭(一般從頭到尾)

雙向鍊錶特點

1.每次在插入或刪除某個節點時, 需要處理四個節點的引用, 而不是兩個. 實現起來要困難一些

2.相對於單向鍊錶, 必然占用記憶體空間更大一些.

3.既可以從頭遍歷到尾, 又可以從尾遍歷到頭

雙向鍊錶的定義:

雙向鍊錶也叫雙鏈表,是鍊錶的一種,它的每個資料結點中都有兩個指標,分別指向直接後繼和直接前驅。所以,從雙向鍊錶中的任意乙個結點開始,都可以很方便地訪問它的前驅結點和後繼結點。下圖為雙向鍊錶的結構圖。

從上中可以看到,雙向鍊錶中各節點包含以下 3 部分資訊:

指標域:用於指向當前節點的直接前驅節點;

資料域:用於儲存資料元素。

指標域:用於指向當前節點的直接後繼節點;

雙向迴圈鍊錶的定義:

雙向鍊錶也可以進行首尾連線,構成雙向迴圈鍊錶,如下圖所示

在建立鍊錶時,只需要在最後將收尾相連即可(建立鍊錶**中已經標出)。其他**稍加改動即可。

雙鏈表的節點結構用 c 語言實現為:

/*隨機數的範圍*/

#define max 100

/*節點結構*/

typedef

struct nodenode;

同單鏈表相比,雙鏈表僅是各節點多了乙個用於指向直接前驅的指標域。因此,我們可以在單鏈表的基礎輕鬆實現對雙鏈表的建立。

需要注意的是,與單鏈表不同,雙鏈表建立過程中,每建立乙個新節點,都要與其前驅節點建立兩次聯絡,分別是:

將新節點的 prior 指標指向直接前驅節點;

將直接前驅節點的 next 指標指向新節點;

這裡給出建立雙向鍊錶的 c 語言實現**:

#define max 100

node *

creatnode

(node *head)

head->pre=

null

; head->next=

null

; head->data=

rand()

%max;

return head;

}node*

creatlist

(node * head,

int length)

else

}/*加上以下兩句就是雙向迴圈鍊錶*/

// list->next=head;

// head->prior=list;

return head;

}

根據資料新增到雙向鍊錶中的位置不同,可細分為以下 3 種情況:

1.新增至表頭

將新資料元素新增到表頭,只需要將該元素與表頭元素建立雙層邏輯關係即可。

換句話說,假設新元素節點為 temp,表頭節點為 head,則需要做以下 2 步操作即可:

temp->next=head; head->prior=temp;

將 head 移至 temp,重新指向新的表頭;

將新元素 7 新增至雙鏈表的表頭,則實現過程如下圖所示:

2.新增至表的中間位置

同單鏈表新增資料類似,雙向鍊錶中間位置新增資料需要經過以下 2 個步驟,如下圖所示:

新節點先與其直接後繼節點建立雙層邏輯關係;

新節點的直接前驅節點與之建立雙層邏輯關係;

3.新增至表尾

與新增到表頭是乙個道理,實現過程如下:

找到雙鏈表中最後乙個節點;

讓新節點與最後乙個節點進行雙層邏輯關係;

/*在第add位置的前面插入data節點*/

node *

insertlisthead

(node * head,

int add,

int data)

else

/*插入到煉表頭,要特殊考慮*/

if(add==1)

else

/*判斷條件為真,說明插入位置為鍊錶尾*/

if(body->next==

null

)else

}return head;

}/*在第add位置的後面插入data節點*/

node *

insertlistend

(node * head,

int add,

int data)

/*判斷條件為真,說明插入位置為鍊錶尾*/

if(body->next==

null

)else

return head;

}

雙鏈表刪除結點時,只需遍歷鍊錶找到要刪除的結點,然後將該節點從表中摘除即可。

例如,刪除元素 2 的操作過程如圖 所示:

/*判斷是否是尾節點*/

else

if(temp->next ==

null

)else

} temp=temp->next;

}printf

("can not find %d!\r\n"

,data)

;return head;

}更改雙鏈表中指定結點資料域的操作是在查詢的基礎上完成的。實現過程是:通過遍歷找到儲存有該資料元素的結點,直接更改其資料域即可。

/*更新函式,其中,add 表示更改結點在雙鏈表中的位置,newelem 為新資料的值*/

node *

modifylist

(node * p,

int add,

int newelem)

temp->data=newelem;

return p;

}

通常,雙向鍊錶同單鏈表一樣,都僅有乙個頭指標。因此,雙鏈表查詢指定元素的實現同單鏈表類似,都是從表頭依次遍歷表中元素。

/*head為原雙鏈表,elem表示被查詢元素*/

intfindlist

(node * head,

int elem)

i++; temp=temp->next;

}/*程式執行至此處,表示查詢失敗*/

return-1

;}

/*輸出鍊錶的功能函式*/

大家的鼓勵是我繼續創作的動力,如果覺得寫的不錯,歡迎關注,點讚,收藏,**,謝謝!以上**均為測試後的**。如有錯誤和不妥的地方,歡迎指出。

C語言雙向鍊錶的基本操作實現

include include intlen 定義雙向鍊錶的節點 typedef struct node node 初始化乙個鍊錶的節點 node create node void scanf d p data p prior null p next null return p 建立含有n個結點的雙...

雙向鍊錶的基本操作 C

參考其他人的雙向鍊錶實現,搞了乙個便於自己理解的練練筆。include include using namespace std 定義乙個節點 typedef struct doublelinknode node 建立乙個鍊錶 node create list int nums,int n retur...

雙向鍊錶 基本操作

test.c define crt secure no warnings 1 include doubleslishtnode.h void test1 initdslist pushback printfdslist popback void test2 pushfront popfront vo...