上一節學習了單向煉表單鍊錶詳解。今天學習雙鏈表。學習之前先對單向鍊錶和雙向鍊錶做個回顧。
單向鍊錶特點:
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...