国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

玩轉(zhuǎn)帶頭雙向鏈表——【數(shù)據(jù)結(jié)構(gòu)】

這篇具有很好參考價值的文章主要介紹了玩轉(zhuǎn)帶頭雙向鏈表——【數(shù)據(jù)結(jié)構(gòu)】。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

玩轉(zhuǎn)帶頭雙向鏈表——【數(shù)據(jù)結(jié)構(gòu)】,數(shù)據(jù)結(jié)構(gòu),鏈表

W...Y的主頁

今天我們接著來說數(shù)據(jù)結(jié)構(gòu)——帶頭雙向鏈表

目錄

帶頭雙向鏈表的實現(xiàn)

結(jié)構(gòu)體的創(chuàng)建

初始化兵創(chuàng)建哨兵節(jié)點

釋放鏈表所以內(nèi)容?

打印鏈表函數(shù)

尾插

尾刪

頭插

?編輯

頭刪

計數(shù)函數(shù)實現(xiàn)

查找數(shù)據(jù)相應(yīng)位置函數(shù)

在pos位置之前插入?

在pos位置刪除?

順序表與鏈表的差別


玩轉(zhuǎn)帶頭雙向鏈表——【數(shù)據(jù)結(jié)構(gòu)】,數(shù)據(jù)結(jié)構(gòu),鏈表

帶頭雙向鏈表(Doubly Linked List with Head)相對于普通的雙向鏈表,添加了一個頭節(jié)點(head node),頭節(jié)點不存儲任何實際的數(shù)據(jù),僅用于指示鏈表的起始位置。下面是帶頭雙向鏈表的一些優(yōu)點:

  1. 鏈表操作方便:帶頭雙向鏈表提供了直接訪問鏈表頭部和尾部的能力,使得鏈表的插入、刪除等操作更加高效。你可以通過頭節(jié)點快速插入第一個元素,也可以通過尾節(jié)點快速插入新元素。同時,由于鏈表的雙向性,你可以輕松地在鏈表中的任意位置進行插入和刪除操作。

  2. 遍歷靈活性:帶頭雙向鏈表可以從頭到尾或從尾到頭兩個方向遍歷。這意味著你可以根據(jù)需要選擇合適的遍歷方式,無論是從前向后還是從后向前遍歷鏈表,都能方便地獲取元素。

  3. 反向查找:帶頭雙向鏈表的一個重要優(yōu)點是可以通過后向鏈接(back link)從任意節(jié)點快速訪問該節(jié)點的前一個節(jié)點。這使得在鏈表中進行反向查找變得高效。與單鏈表相比,帶頭雙向鏈表的反向查找時間復(fù)雜度從O(n)降至O(1),這對某些應(yīng)用程序可能非常重要。

  4. 方便的刪除節(jié)點:在帶頭雙向鏈表中,刪除一個節(jié)點不需要訪問其前一個節(jié)點,只需修改當(dāng)前節(jié)點的前后鏈接即可。這樣,節(jié)點的刪除操作變得更為方便和高效。

帶頭雙向循環(huán)鏈表:結(jié)構(gòu)最復(fù)雜,一般用在單獨存儲數(shù)據(jù)。實際中使用的鏈表數(shù)據(jù)結(jié)構(gòu),都是帶頭雙向循環(huán)鏈表。另外這個結(jié)構(gòu)雖然結(jié)構(gòu)復(fù)雜,但是使用代碼實現(xiàn)以后會發(fā)現(xiàn)結(jié)構(gòu)會帶 來很多優(yōu)勢,實現(xiàn)反而簡單了,后面我們代碼實現(xiàn)了就知道了。

帶頭雙向鏈表的實現(xiàn)

結(jié)構(gòu)體的創(chuàng)建

typedef int LTDataType;

typedef struct ListNode
{
	int data;
	struct ListNode* next;
	struct ListNode* prev;
}LTNode;

創(chuàng)建結(jié)構(gòu)體使用typedef將其改名LTNode方便使用,創(chuàng)建next和prev節(jié)點用來保存下一個節(jié)點與上一個節(jié)點。

初始化兵創(chuàng)建哨兵節(jié)點

我們創(chuàng)建哨兵位時,可以在data中間增加-1,創(chuàng)建好后將next與prev全部指向自己。但是這個功能與怎加節(jié)點函數(shù)內(nèi)容及其相似,所以我們可以先創(chuàng)建節(jié)點函數(shù),然后再初始化哨兵位時將其調(diào)用即可,防止冗余現(xiàn)象。

LTNode* BuyLTNode(LTDataType x)
{
	LTNode* node = (LTNode*)malloc(sizeof(LTNode));
	if (node == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	node->data = x;
	node->prev = NULL;
	return node;
}
LTNode* LTInit()
{
	LTNode* phead = BuyLTNode(-1);
	phead->next = phead;
	phead->prev = phead;

	return phead;
}

?我們再創(chuàng)建好兩個函數(shù)時,讓LTInit函數(shù)去調(diào)用BuyLTNode函數(shù),將哨兵位初始化即可。

釋放鏈表所以內(nèi)容?

因為鏈表使用realloc開辟的空間全部在堆區(qū),所以必須將鏈表開辟的空間全部釋放,防止內(nèi)存泄漏。

void LTDestory(LTNode* phead)
{
	assert(phead);
	LTNode* cur = phead->next;
	while (cur != phead)
	{
		LTNode* next = cur->next;
		free(cur);
		cur = next;
	}
	free(phead);
	phead = NULL;
}

打印鏈表函數(shù)

在打印鏈表時,我們要將次鏈表與單鏈表區(qū)分。單鏈表只需找到尾NULL即可停止,而雙向鏈表的尾部指向哨兵位,所以我們可以換一種方法進行檢測。

void LTPrint(LTNode* phead)
{
	assert(phead);
	LTNode* cur = phead->next;
	printf("phead<->");
	while (cur != phead)
	{
		printf("%d<->", cur->data);
		cur = cur->next;
	}
}

我們創(chuàng)建一個遍歷指針cur,讓cur = phead->next指向哨兵位下一個節(jié)點。然后進行遍歷,如果遍歷返回到哨兵位phead停止即可。

尾插

玩轉(zhuǎn)帶頭雙向鏈表——【數(shù)據(jù)結(jié)構(gòu)】,數(shù)據(jù)結(jié)構(gòu),鏈表

尾插相對于單鏈表也非常方便,不用遍歷找尾節(jié)點,只需要訪問phead的prev即可找到尾節(jié)點。?

void LTPushBack(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* tail = phead->prev;
	LTNode* newnode = BuyLTNode(x);

	newnode->prev = tail;
	newnode->next = phead;
	tail->next = newnode;
	phead->prev = newnode;
}

玩轉(zhuǎn)帶頭雙向鏈表——【數(shù)據(jù)結(jié)構(gòu)】,數(shù)據(jù)結(jié)構(gòu),鏈表

尾刪

我們首先得檢測phead哨兵位是否為空,如果鏈表為空我們也不能正常進行刪除,所以我們得繼續(xù)判斷phead->next != phead。自己的下一個節(jié)點不能指向自己。

void LTPopBack(LTNode* phead)
{
	assert(phead);
	assert(phead->next != phead);
	LTNode* tail = phead->prev;
	phead->prev = tail->prev;
	tail->prev->next = phead;
	free(tail);

}

刪除就非常簡單,訪問最后一個節(jié)點記作tail,將phead連接尾節(jié)點的地址切換成尾節(jié)點的上一個節(jié)點,然后將尾節(jié)點上一個節(jié)點的next換成哨兵位地址,free掉tail尾節(jié)點即可。?

頭插

頭插與尾插原理基本相同,只需要將哨兵位的內(nèi)容進行改變即可。

void LTPushFront(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* newnode = BuyLTNode(x);
	/*newnode->next = phead->next; 
	phead->next->prev = newhead;
	phead->next = newhead;
	newhead->prev = phead;*/
	LTNode* first = phead->next;
	phead->next = newnode;
	newnode->prev = phead;
	first->prev = newnode;
	newnode->next = first;
}

玩轉(zhuǎn)帶頭雙向鏈表——【數(shù)據(jù)結(jié)構(gòu)】,數(shù)據(jù)結(jié)構(gòu),鏈表

?我們可以參照上述代碼進行頭插,分別有兩種方法。第一種(已注釋)是不創(chuàng)建任何指針變量進行交換替代,第二種(未注釋)即創(chuàng)建變量進行交換。第一種方法再交換次序上必須嚴(yán)謹(jǐn),先進行尾節(jié)點的交互,再進行首節(jié)點的交互,否則會交換失敗出現(xiàn)錯誤數(shù)據(jù)。

頭刪

在刪除時,務(wù)必檢測鏈表是否為空,鏈表是否只有哨兵位方可進行刪除操作。

void LTPopFront(LTNode* phead)
{
	assert(phead);
	assert(phead->next != phead);
	LTNode* first = phead->next;
	LTNode* second = first->next;
	free(first);
	phead->next = second;
	second->prev = phead;
}

計數(shù)函數(shù)實現(xiàn)

當(dāng)我們錄入數(shù)據(jù)量過大時,為了方便計數(shù)所創(chuàng)建的函數(shù)。‘

int LTsize(LTNode* phead)
{
	assert(phead);
	int size = 0;
	LTNode* cur = phead->next;
	while (cur != phead)
	{
		++size;
		cur = cur->next;
	}
	return size;
}

這里只需遍歷鏈表種的每一個節(jié)點直到返回到哨兵位即可。

查找數(shù)據(jù)相應(yīng)位置函數(shù)

當(dāng)操作人員想知道某個數(shù)據(jù)在鏈表中的位置并進行操作時,我們即可調(diào)用此函數(shù)來返回相應(yīng)數(shù)據(jù)所在節(jié)點的地址。

LTNode* LTFind(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* cur = phead->next;
	while(cur != phead)
	{
		if (cur->data == x)
			return cur;
	}
		return NULL;
}

這里我們使用暴力查找的算法進行整組鏈表搜索,找到對應(yīng)數(shù)據(jù)即可返回。

在pos位置之前插入?

這里我們就需要與查找位置函數(shù)進行聯(lián)動配合進行調(diào)用。

void LTInsert(LTNode* pos, LTDataType x)
{
	assert(pos);
	LTNode* posprev = pos->prev;
	LTNode* newnode = BuyLTNode(x);
	posprev->next = newnode;
	newnode->next = pos;
	newnode->prev = posprev;
	pos->prev = newnode;
}

這里其實與頭插尾插原理一樣,所以我們也可以用此函數(shù)進行頭插尾插,只需將pos參數(shù)傳入正確,分別為phead->next(頭插)、phead->prev(尾插)。

在pos位置刪除?

void LTErase(LTNode* pos)
{
	assert(pos);
	LTNode* posprev = pos->prev;
	LTNode* posnext = pos->next;
	free(pos);
	posprev->next = posnext;
	posnext->prev = posprev;
}

這里也是與頭刪尾刪原理相同,只需將參數(shù)傳入正確即可變成頭刪和尾刪。

順序表與鏈表的差別

玩轉(zhuǎn)帶頭雙向鏈表——【數(shù)據(jù)結(jié)構(gòu)】,數(shù)據(jù)結(jié)構(gòu),鏈表

所以在不同情況下選擇不同的數(shù)據(jù)結(jié)構(gòu)時是很關(guān)鍵的,我們需要足夠了解其中的差別與優(yōu)勢,才能滿足各種問題下不同的需求。文章來源地址http://www.zghlxwxcb.cn/news/detail-634508.html

到了這里,關(guān)于玩轉(zhuǎn)帶頭雙向鏈表——【數(shù)據(jù)結(jié)構(gòu)】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【數(shù)據(jù)結(jié)構(gòu)】—帶頭雙向循環(huán)鏈表的實現(xiàn)(完美鏈表)

    【數(shù)據(jù)結(jié)構(gòu)】—帶頭雙向循環(huán)鏈表的實現(xiàn)(完美鏈表)

    鏈表結(jié)構(gòu)一共有八種形式,在前面的文章里已經(jīng)講完了不帶頭單向非循環(huán)鏈表的實現(xiàn),但是我們發(fā)現(xiàn)該鏈表實現(xiàn)尾插與尾刪時比較麻煩,要先從頭節(jié)點進行遍歷,找到尾節(jié)點,時間復(fù)雜度為O(N),而本次所講的帶頭雙向循環(huán)單鏈表,則可以直接找到尾節(jié)點。 雖然該鏈表看起來

    2024年01月25日
    瀏覽(18)
  • 【數(shù)據(jù)結(jié)構(gòu)初階】四、線性表里的鏈表(帶頭+雙向+循環(huán) 鏈表 -- C語言實現(xiàn))

    【數(shù)據(jù)結(jié)構(gòu)初階】四、線性表里的鏈表(帶頭+雙向+循環(huán) 鏈表 -- C語言實現(xiàn))

    ========================================================================= 相關(guān)代碼gitee自取 : C語言學(xué)習(xí)日記: 加油努力 (gitee.com) ?========================================================================= 接上期 : 【數(shù)據(jù)結(jié)構(gòu)初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實現(xiàn))-CSDN博客 ?====

    2024年02月08日
    瀏覽(30)
  • 【數(shù)據(jù)結(jié)構(gòu)和算法】實現(xiàn)帶頭雙向循環(huán)鏈表(最復(fù)雜的鏈表)

    【數(shù)據(jù)結(jié)構(gòu)和算法】實現(xiàn)帶頭雙向循環(huán)鏈表(最復(fù)雜的鏈表)

    前文,我們實現(xiàn)了認(rèn)識了鏈表這一結(jié)構(gòu),并實現(xiàn)了無頭單向非循環(huán)鏈表,接下來我們實現(xiàn)另一種常用的鏈表結(jié)構(gòu),帶頭雙向循環(huán)鏈表。如有仍不了解單向鏈表的,請看這一篇文章(7條消息) 【數(shù)據(jù)結(jié)構(gòu)和算法】認(rèn)識線性表中的鏈表,并實現(xiàn)單向鏈表_小王學(xué)代碼的博客-CSDN博客

    2024年01月17日
    瀏覽(28)
  • 數(shù)據(jù)結(jié)構(gòu):鏈表基礎(chǔ)OJ練習(xí)+帶頭雙向循環(huán)鏈表的實現(xiàn)

    數(shù)據(jù)結(jié)構(gòu):鏈表基礎(chǔ)OJ練習(xí)+帶頭雙向循環(huán)鏈表的實現(xiàn)

    目錄 一.leetcode劍指 Offer II 027.?回文鏈表 1.問題描述 2.問題分析與求解 (1) 快慢指針法定位鏈表的中間節(jié)點 (2)?將鏈表后半部分進行反轉(zhuǎn) 附:遞歸法反轉(zhuǎn)鏈表 (3)?雙指針法判斷鏈表是否回文 二.帶頭雙向循環(huán)鏈表的實現(xiàn) 1.頭文件 2.節(jié)點內(nèi)存申請接口和鏈表初始化接口 3.鏈表的打

    2024年02月02日
    瀏覽(30)
  • 鏈接未來:深入理解鏈表數(shù)據(jù)結(jié)構(gòu)(二.c語言實現(xiàn)帶頭雙向循環(huán)鏈表)

    鏈接未來:深入理解鏈表數(shù)據(jù)結(jié)構(gòu)(二.c語言實現(xiàn)帶頭雙向循環(huán)鏈表)

    上篇文章簡述講解了鏈表的基本概念并且實現(xiàn)了無頭單向不循環(huán)鏈表:鏈接未來:深入理解鏈表數(shù)據(jù)結(jié)構(gòu)(一.c語言實現(xiàn)無頭單向非循環(huán)鏈表)-CSDN博客 那今天接著給大家?guī)韼ь^雙向循環(huán)鏈表的實現(xiàn) : 頭文件DoubleList.h:用來基礎(chǔ)準(zhǔn)備(常量定義,typedef),鏈表表的基本框架

    2024年01月16日
    瀏覽(58)
  • 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計題目——鏈表綜合算法設(shè)計、帶頭雙向循環(huán)鏈表、插入、顯示、刪除、修改、排序

    數(shù)據(jù)結(jié)構(gòu)課程設(shè)計題目——鏈表綜合算法設(shè)計、帶頭雙向循環(huán)鏈表、插入、顯示、刪除、修改、排序

    ??課程設(shè)計題目1–鏈表綜合算法設(shè)計 ??一、設(shè)計內(nèi)容 ??已知簡單的人事信息系統(tǒng)中職工記錄包含職工編號(no)、職工姓名(name)、部門名稱(depname)、職稱(title)和工資數(shù)(salary)等信息(可以增加其他信息),設(shè)計并完成一個簡單的人事信息管理系統(tǒng),要求完成但不

    2024年02月08日
    瀏覽(26)
  • 【數(shù)據(jù)結(jié)構(gòu)】帶頭雙向循環(huán)鏈表

    【數(shù)據(jù)結(jié)構(gòu)】帶頭雙向循環(huán)鏈表

    ??????? 個人主頁:簡 料 ???? 所屬專欄:C++ ???? 個人社區(qū):越努力越幸運社區(qū) ???? 簡? ? ?? 介: 簡料簡料,簡單有料~在校大學(xué)生一枚,專注C/C++/GO的干貨分享,立志成為您的好幫手 ~ C/C++學(xué)習(xí)路線 (點擊解鎖) ?? C語言階段(已結(jié)束) ?? 數(shù)據(jù)結(jié)構(gòu)與算法(ing) ?

    2024年01月16日
    瀏覽(33)
  • 數(shù)據(jù)結(jié)構(gòu)---帶頭雙向循環(huán)鏈表

    數(shù)據(jù)結(jié)構(gòu)---帶頭雙向循環(huán)鏈表

    什么是雙向帶頭循環(huán)鏈表? 上面簡單的一個非空 帶頭循環(huán)雙向鏈表邏輯圖 如何定義一個雙向鏈表? 根據(jù)圖和代碼可以看雙向鏈表就是單鏈表的每個結(jié)點中,在設(shè)置一個指向前驅(qū)節(jié)點的指針 簡單認(rèn)識之后,對他進行初始化(申請一個頭節(jié)點,讓前驅(qū)和后驅(qū)指針都指向自己) 代碼

    2024年02月07日
    瀏覽(17)
  • 數(shù)據(jù)結(jié)構(gòu)-帶頭雙向循環(huán)鏈表

    數(shù)據(jù)結(jié)構(gòu)-帶頭雙向循環(huán)鏈表

    前言: 鏈表有很多種,上一章結(jié),我復(fù)盤了單鏈表,這一章節(jié),主要針對雙鏈表的知識點進行,整理復(fù)盤,如果將鏈表分類的話,有很多種,我就學(xué)習(xí)的方向考察的重點,主要針對這兩種鏈表進行整理。 帶頭雙向循環(huán)鏈表:結(jié)構(gòu)最復(fù)雜,一般用在單獨存儲數(shù)據(jù)。實際中使用

    2023年04月09日
    瀏覽(28)
  • 帶頭雙向循環(huán)鏈表--數(shù)據(jù)結(jié)構(gòu)

    帶頭雙向循環(huán)鏈表--數(shù)據(jù)結(jié)構(gòu)

    ????????????????????????Take your time ! ???????????????????????? ??個人主頁:??????大魔王?????? ??所屬專欄:??魔王的修煉之路–數(shù)據(jù)結(jié)構(gòu)?? 如果你覺得這篇文章對你有幫助,請在文章結(jié)尾處留下你的 點贊 ??和 關(guān)注 ??,支持一

    2024年02月01日
    瀏覽(40)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包