手撸双链表,图解
C語言,鏈表
C++實(shí)現(xiàn)單向鏈表
深入理解Linux內(nèi)核鏈表
跟單鏈表不同,雙鏈表的節(jié)點(diǎn)包含兩個(gè)指針,一個(gè)指針指向上一個(gè)元素,一個(gè)指針指向下一個(gè)元素。
▌如下圖
學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)的時(shí)候,要像認(rèn)識(shí)一個(gè)人一樣,要了解這個(gè)人有什么特點(diǎn),比如喜歡打球,喜歡喝酒之類的。學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)也是一樣,要了解數(shù)據(jù)結(jié)構(gòu)的特點(diǎn)。
我們要學(xué)習(xí)雙鏈表,需要搞明白鏈表這幾個(gè)特點(diǎn)
創(chuàng)建鏈表
往鏈表插入數(shù)據(jù)
刪除鏈表中的某個(gè)數(shù)據(jù)
刪除整個(gè)鏈表
查找鏈表
反轉(zhuǎn)鏈表
▌先看看如何創(chuàng)建一個(gè)鏈表
創(chuàng)建一個(gè)鏈表無非就是搞定鏈表頭,沒有頭的鏈表就是死鏈表,有頭就表示這個(gè)鏈表是存在的。當(dāng)然了,可能會(huì)存在循環(huán)鏈表,只有位置,沒有固定的頭指針。
創(chuàng)建一個(gè)pHead,并且以后pHead頭指針保持不動(dòng),就表示我們創(chuàng)建好了一個(gè)鏈表頭指針。
typedef?struct?Node{struct?Node?*prev;struct?Node?*next;int?elements; }pNode;pNode?*?CreateHead(void) {pNode?*head?=?NULL;head?=?(pNode?*)malloc(sizeof(struct?Node));head->next?=?NULL;head->prev?=?NULL;return?head; }▌插入元素
插入元素的方式有多種,可以頭插,可以尾插,也可以任意插,我只寫了簡單的插入方式-尾插。
▌遍歷一個(gè)鏈表
遍歷鏈表是常規(guī)的操作,但是遍歷鏈表的方法有很多種,可以從頭開始遍歷,可以從尾部開始,在涉及二分查找的時(shí)候可以從中間某個(gè)位置開始遍歷。雖然方法很多,但是我只寫了一種方法,就是從頭開始遍歷鏈表,因?yàn)槭亲詈唵蔚摹?/p>int?TraverseLink(pNode?*head) {if(head?==?NULL){PRINTK_LINK("Head?NULL\n");return?(-1);}pNode?*?pTemp?=?head;while(pTemp->next?!=?NULL){pTemp?=?pTemp->next;PRINTK_LINK("Element:%d\n",pTemp->elements);}return?(0); }
▌刪除鏈表
刪除整個(gè)鏈表是把鏈表的每個(gè)元素都刪除,并且把頭也刪除,并且把頭指針指向NULL。如果需要找到鏈表中的某個(gè)元素并刪除,就需要先找到鏈表中的元素,刪除掉,并且把前后的兩個(gè)元素連在一起。
int?DeleteLink(pNode?*head) {if(head?==?NULL){PRINTK_LINK("Head?NULL\n");return?(-1);}pNode?*?pTemp?=?head;while(pTemp->next?!=?NULL){pTemp?=?pTemp->next;}while(pTemp?!=?NULL){free(pTemp); pTemp = NULL;pTemp?=?pTemp->prev;}return?(0); }▌完整代碼
#include?"stdio.h" #include?"string.h" #include?"stdlib.h"#define?LOG_TAG?"[LINK]:?%s()?line:?%d?" #define?PRINTK_LINK(fmt,?args...)??printf(LOG_TAG?fmt,?__FUNCTION__,?__LINE__,??##args)typedef?struct?Node{struct?Node?*prev;struct?Node?*next;int?elements; }pNode;pNode?*?CreateHead(void) {pNode?*head?=?NULL;head?=?(pNode?*)malloc(sizeof(struct?Node));head->next?=?NULL;head->prev?=?NULL;return?head; }int?InsertElement(pNode?*head,int?element) {if(head?==?NULL){PRINTK_LINK("Head?NULL\n");return?(-1);}pNode?*?pTemp?=?head;while(pTemp->next?!=?NULL){pTemp?=?pTemp->next;}pNode?*?pElement?=?(pNode?*)malloc(sizeof(struct?Node));pElement->elements?=?element;pTemp->next?=?pElement;pElement->prev?=?pTemp;PRINTK_LINK("Element:%d\n",element);return?(0); }int?TraverseLink(pNode?*head) {if(head?==?NULL){PRINTK_LINK("Head?NULL\n");return?(-1);}pNode?*?pTemp?=?head;while(pTemp->next?!=?NULL){pTemp?=?pTemp->next;PRINTK_LINK("Element:%d\n",pTemp->elements);}return?(0); }int?DeleteLink(pNode?*head) {if(head?==?NULL){PRINTK_LINK("Head?NULL\n");return?(-1);}pNode?*?pTemp?=?head;while(pTemp->next?!=?NULL){pTemp?=?pTemp->next;}while(pTemp?!=?NULL){free(pTemp);pTemp?=?pTemp->prev;}return?(0); }int?main() {pNode?*?pHead?=?CreateHead();InsertElement(pHead,13);InsertElement(pHead,8);InsertElement(pHead,0);InsertElement(pHead,4);InsertElement(pHead,485);InsertElement(pHead,94);TraverseLink(pHead);DeleteLink(pHead);return?0; }▌程序輸出
ubuntu1804:~/c$?gcc?shuanglianbiao.c?&&?./a.out [LINK]:?InsertElement()?line:?40?Element:13 [LINK]:?InsertElement()?line:?40?Element:8 [LINK]:?InsertElement()?line:?40?Element:0 [LINK]:?InsertElement()?line:?40?Element:4 [LINK]:?InsertElement()?line:?40?Element:485 [LINK]:?InsertElement()?line:?40?Element:94 [LINK]:?TraverseLink()?line:?56?Element:13 [LINK]:?TraverseLink()?line:?56?Element:8 [LINK]:?TraverseLink()?line:?56?Element:0 [LINK]:?TraverseLink()?line:?56?Element:4 [LINK]:?TraverseLink()?line:?56?Element:485 [LINK]:?TraverseLink()?line:?56?Element:94▌總結(jié)
我上面的代碼只設(shè)計(jì)了鏈表頭,如果設(shè)計(jì)鏈表尾部指針,應(yīng)用會(huì)更加靈活。
相比于單鏈表,雙鏈表的操作會(huì)更加靈活,當(dāng)然,每一個(gè)節(jié)點(diǎn)都需要新增一個(gè)指向于上一個(gè)位置的指針。
雙鏈表還可以把頭尾連接起來變成一個(gè)環(huán)形隊(duì)列。
鏈表相對(duì)于數(shù)組來說,插入和刪除數(shù)據(jù)非常快,因?yàn)椴恍枰苿?dòng)數(shù)據(jù),只需要改變指針的指向。
雙鏈表內(nèi)存利用率高,如果是內(nèi)存緊張的硬件設(shè)備,使用鏈表操作可以節(jié)省內(nèi)存。相對(duì)于數(shù)組,鏈表可以做到按需分配內(nèi)存。
鏈表是一種基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),建議做到自己能寫出一個(gè)鏈表,不要求十全十美,我曾經(jīng)面試遇到讓我手?jǐn)]一個(gè)棧。相對(duì)于那些C語言基礎(chǔ),寫代碼更能彰顯程序員的技術(shù)。
推薦閱讀:
專輯|Linux文章匯總
專輯|程序人生
專輯|C語言
我的知識(shí)小密圈
關(guān)注公眾號(hào),后臺(tái)回復(fù)「1024」獲取學(xué)習(xí)資料網(wǎng)盤鏈接。
歡迎點(diǎn)贊,關(guān)注,轉(zhuǎn)發(fā),在看,您的每一次鼓勵(lì),我都將銘記于心~
總結(jié)
- 上一篇: python 读取 pdf 文档
- 下一篇: Iris数据集可视化