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

【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下)

這篇具有很好參考價值的文章主要介紹了【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

知識回顧

? ? ? ? 在前面的學習中,我們已經了解到了鏈表(線性表的鏈式存儲)的一些基本特點,并且深入的研究探討了單鏈表的一些特性,我們知道,單鏈表在實現插入刪除上,是要比順序表方便的,但是,單鏈表中每個結點僅存在一個指針指向其后續(xù)結點,那么如果我們想要找到其前面的節(jié)點,則需要從頭部開始遍歷,這是十分不方便的;那么,是不是對其添加一些元素或特性,使其的操作更加簡單呢?那么我們就來看下這節(jié)將要學習的一些鏈表。?

雙鏈表

? ? ? ? 我們知道,單鏈表中每個結點只有一個指向其后續(xù)的指針,這邊可以使得單鏈表可以從前往后的遍歷整個鏈表,但如果我們想要去訪問某個結點的前驅節(jié)點時,則需要從頭開始遍歷,這樣就會消耗較多的時間;那么為了解決這一問題我們引入雙鏈表。

【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下),考研408之數據結構,數據結構,鏈表,408,考研

?????????我們不難觀察到,雙鏈表則是在單鏈表的基礎上,在結點中又添加了一個指針,用于指向該結點的前驅結點,那么這樣的話,我們也就可以通過一個結點很好的去查詢其前驅和后繼結點了,雖然我們增加了存儲密度,但在對鏈表的操作上就更加的靈活。

結點初始化:

typedef struct DNode{
	int data ;
	struct DNode *prior, *next ;
}DNode, *DLinkList;

雙鏈表的插入

? ? ? ? 實際上,雙鏈表的插入是類似于單鏈表的插入的,只不過,由于雙鏈表存在指向后續(xù)結點以及前驅結點的指針,所以在進行插入操作時,我們需要對這兩個指針分別進行類似的操作即可。

【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下),考研408之數據結構,數據結構,鏈表,408,考研

? ? ? ? 如圖所示,我們若要在雙鏈表中插入x,那么我們首先需要讓x結點的后續(xù)指針指向插入位置后結點,之后再將插入位置后結點(c)的前驅指針指向x;之后再讓x結點的前驅指針指向插入位置的前驅結點(a),之后再將插入位置的前驅結點(a)的后繼指針指向x;這樣我們就成功的將x插入到鏈表之中了。

????????需要思考的是,當我們的插入位置為鏈表的末尾時,我們應該怎么去操作呢?這當然也不難操作,通過對雙鏈表的觀察,我們知道,在其末尾結點的后續(xù)結點會指向NULL;那么這時就不會存在一個后面的結點指向末尾結點了,也就是說,在之前我們的結點是存在兩個指向結點的箭頭和兩個指出的箭頭;但到了末尾就缺少一個指向的箭頭。

? ? ? ? 知道了這層差異,那么我們就要對其進行相應的處理,首先我們需要判斷我們插入位置前的結點是否指向NULL,當其指向NULL時,則證明我們插入的為末尾結點,這里我們對前續(xù)的操作不變,只不過在對其后續(xù)操作時,我們只需要讓其指向NULL(也就前末結點指向的位置)即可,不需要進行指向插入結點的操作。

? ? ? ? 當然,插入首位的方法也同上所示,只不過從特殊處理后續(xù)操作轉變?yōu)樘厥馓幚砬膀尣僮骷纯伞?/p>

//插入
bool InsertNextDNode(DNode *p, DNode *s) {
	if(p == NULL || s == NULL)	return false;
	
	s->next = p->next;
	if(p->next != NULL) {
		p->next->prior = s;
	}
	p->next = s;
	s->prior = p;
	return true;
}

雙鏈表的刪除

? ? ? ? 對于刪除操作,其原理也與單鏈表的操作類似,只不過其具有兩個指針,所以我們需要更改兩個指針的指向即可。

【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下),考研408之數據結構,數據結構,鏈表,408,考研

? ? ? ? 對于雙倆表的刪除操作,例如我們需要刪除b結點,那么我們只需要讓a的后續(xù)指針指向c(b后續(xù)指針指向位置),讓c的前驅指針指向a(b前驅指針指向位置),這樣我們就可以刪除b結點了。

? ? ? ? 例如:刪除p指針后的結點b。

p->next=q->next;
q->next->prior=p;
free(q);

? ? ? ? 當然,刪除前驅結點的方法也與之類似,我們更改其相應的指針指向即可。

? ? ? ? 那我們如果刪除的結點位于雙鏈表的頭部或者尾部呢?這樣對于我們的操作是否存在什么影響?下面我們來看一下:(在這里我們以末結點為例,實際上頭結點刪除方法與其類似)

【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下),考研408之數據結構,數據結構,鏈表,408,考研?

? ? ? ? 當我們遇到尾結點時,由于我們末尾元素后指向NULL,所以其不存在一個指向前的指針,也就是說,如果我們想要刪除末尾元素的話,我們就只需要讓其前面的元素結點向后指向NULL即可,之后再釋放我們想要刪除的末尾結點,就可以解決這種問題了。

//刪除(p后的節(jié)點) 
bool DeleteNextDNode(DNode *p) {
	if(p == NULL)	return false;
	DNode *q = p->next;
	if(q == NULL)	return false;
	
	p->next = q->next;
	if(q->next != NULL)	q->next->prior = p;
	
	free(q);
	return true;
}

雙鏈表的遍歷?

? ? ? ? 至于遍歷雙鏈表這里由于我們前面的學習,這部分的內容就十分的簡單了。我們就像單鏈表遍歷一樣,通過頭指針或頭結點開始從頭部或者我們所指定的某一點,以此遍歷其next指針,直到其指向NULL為止,那么這樣我們是不是就可以成功的從頭部遍歷一遍鏈表了呢!

? ? ? ? 乍一聽,這與單鏈表是沒什么不同的,但由于我們雙鏈表是一個結點存在兩個指針的(也就是指向前的prior以及指向后續(xù)的next)指針,所以我們在進行遍歷的時候,也就可以去嘗試更多的遍歷方法了,我們可以嘗試從后向前遍歷。

? ? ? ? 這與前面的從前向后遍歷并沒有什么不同,只是我們需要從尾部向頭部遍歷的時候需要不停的訪問改結點的prior指針,直到其指向NULL為止。

//遍歷
//從前向后遍歷
void PriorFindList(DLinkList L) {
	DNode *p = L->next;
	while(p != NULL) {
		cout << p->data << " " ;
		p = p->next;
	}
	cout << endl;
}
//從后向前遍歷
void AfterFindList(DLinkList L) {
	DNode *p = L;
	while(p->next != NULL) {
		p = p->next;
	}
	
	while(p!=L) {
		cout << p->data << " " ;
		p = p->prior;
	}
	cout << endl;
}

循環(huán)鏈表

? ? ? ? 循環(huán)鏈表又可以分為循環(huán)單鏈表和循環(huán)雙鏈表。其原理是十分相同的。

循環(huán)單鏈表

【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下),考研408之數據結構,數據結構,鏈表,408,考研

? ? ? ? 通過圖我們不難看出,上面的鏈表是我們已經討論過多次的單鏈表,其尾結點指針指向NULL,那么我們怎么使其變成循環(huán)鏈表呢?

? ? ? ? 循環(huán)、循環(huán),顧名思義,就是當我們訪問某一序列最后一個元素時,緊接著我們就可以以相同的操作去訪問該序列第一個元素;在這里對于鏈表也是相同的:也就是當我們訪問的某鏈表的尾結點時,我們依舊可以通過常規(guī)的訪問該結點的next指針的方法去訪問到該鏈表的頭結點。

? ? ? ? 那么這樣我們的思路就十分清晰了,我們就只需要在創(chuàng)立鏈表時,使其的末結點的next指針指向該鏈表的頭結點,這樣我們就可以很輕松的實現循環(huán)單鏈表了。

? ? ? ? 那么我們?yōu)槭裁匆獙W習單鏈表呢??

? ? ? ? 如果我們只是使用單鏈表,當我們有某一結點的位置時,我們可以通過單鏈表的特性去合理的訪問到其后面的各個結點;但其前面的結點對于我們來說就是未知的了。

【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下),考研408之數據結構,數據結構,鏈表,408,考研

? ? ? ? 為了解決這個問題,我們就可以引入循環(huán)單鏈表,這樣我們在得到某一結點位置后,我們依次訪問最終就可以成功的訪問到該鏈表頭結點,那么我們指定結點前的區(qū)域就不再是未知的了。

【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下),考研408之數據結構,數據結構,鏈表,408,考研?

? ? ? ? ?在引入循環(huán)鏈表時,我們就可以設立一個尾指針,甚至說尾指針在這里要比頭指針更加的方便!我們不難知道,對于頭指針來說訪問鏈表頭部需要O(1)的時間復雜度、訪問尾部時需要O(n)的時間復雜度。但對于循環(huán)單鏈表的話,我們就可以使用O(1)的時間復雜度訪問其頭結點和尾結點,對于尾結點沒什么好說的,因為其就指向尾結點我們直接訪問即可;但對于頭結點我們在訪問時僅僅需要訪問尾結點的next指針,由于其是循環(huán)的,所以我們就可以僅用O(1)的時間復雜度就訪問到了頭結點,這無疑來說節(jié)省了很多時間。那么同理,我們在遇到某些操作中包含需要查找尾結點的操作時,這樣都可以節(jié)省其時間。

循環(huán)雙鏈表?

【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下),考研408之數據結構,數據結構,鏈表,408,考研

? ? ? ? 如上圖中上方的鏈表一樣,該鏈表是剛才我們已經了解過的雙鏈表;那么其循環(huán)雙鏈表的建立實際上是類似于循環(huán)單鏈表的;只不過需要注意的是,由于我們的雙鏈表的每個結點是有兩個指針的,所以我們在使其尾部指向頭部時,也要去更改頭部的prior指針,使其指向鏈表的尾,這樣我們就可以實現循環(huán)雙鏈表了。

? ? ? ? ?這里,由于循環(huán)鏈表于前面的單雙鏈表相似,所以這里就不給出其完整代碼實現了,實際上我們只需對一些地方的代碼進行特定的修改就可以得到該循環(huán)鏈表的代碼了。

靜態(tài)鏈表

? ? ? 通過前面的學習,我們知道,單鏈表各個結點的存儲,在我們計算機的內存中是完全隨機雜亂的,我們需要通過指針去link(連接)這些結點;那么我們可不可以在內存中申請一塊連續(xù)的存儲空間,去進行存儲這個鏈表呢?

? ? ? ? 當然這乍一聽與數組十分的相似,只不過我們需要通過這一連續(xù)的存儲空間去實現鏈表的功能,也就是需要通過next"指針"去指向后續(xù)節(jié)點。

【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下),考研408之數據結構,數據結構,鏈表,408,考研

? ? ? ? 那么這里我們就可以參考數組,我們將結點劃分為存數據的data和存下一位置的數組下標next;這樣我們在存入一個元素時首先判斷該數組位置是否已存入數據,若沒有存入數據的話,我們將其存入,并將上一尾結點的next更新為該結點的數組下標。

? ? ? ? 這里我們通過next去串聯(lián)數組的下標,進而實現鏈表功能。

【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下),考研408之數據結構,數據結構,鏈表,408,考研

? ? ? ? ? 例如上圖所示,我們可以將結點的data默認初始化為 -2 (也就是說,當我們在某結點進行存入數據時,可以判斷下其next是否為-2,若不是-2則說明該結點已經存在元素),那么我們觀察圖中鏈表,可以看出這里我們:頭->數組[2]->數組[1]->數組[6]->數組[3]->-1;-1則表明到達了尾部。

優(yōu)點:增、刪 操作不需要大量移動元素 缺點:不能隨機存取,只能從頭結點開始依次往后查 找;容量固定不可變

適用場景:①不支持指針的低級語言;②數據元素數 量固定不變的場景(如操作系統(tǒng)的文件分配表FAT)

代碼

雙鏈表代碼

// 2.4 雙鏈表

#include <bits/stdc++.h>

using namespace std ;

typedef struct DNode{
	int data ;
	struct DNode *prior, *next ;
}DNode, *DLinkList;

//初始化
bool InitDLinkList(DLinkList &L) {
	L = (DNode *)malloc(sizeof(DNode)) ;
	if(L == NULL)	return false ;	//分配失敗 
	
	L->next = NULL;
	L->prior = NULL;
	return true;
}

//尾插法建立
DLinkList DList_TailInsert(DLinkList &L) {
	int x;
	cin >> x;
	
	DNode *s, *r = L;
	
	while(x!=9999) {
		s = (DNode *)malloc(sizeof(DNode)) ;
		s->data = x;
		r->next = s;
		s->prior = r;
		r = s;
		cin >> x;
	}
	
	r->next = NULL;
	return L;
} 

//插入
bool InsertNextDNode(DNode *p, DNode *s) {
	if(p == NULL || s == NULL)	return false;
	
	s->next = p->next;
	if(p->next != NULL) {
		p->next->prior = s;
	}
	p->next = s;
	s->prior = p;
	return true;
}

//刪除(p后的節(jié)點) 
bool DeleteNextDNode(DNode *p) {
	if(p == NULL)	return false;
	DNode *q = p->next;
	if(q == NULL)	return false;
	
	p->next = q->next;
	if(q->next != NULL)	q->next->prior = p;
	
	free(q);
	return true;
}

//銷毀
void DestoryList(DLinkList &L) {
	while(L->next != NULL){
		DeleteNextDNode(L);
	}
	free(L);
	L=NULL;
} 

//遍歷
//從前向后遍歷
void PriorFindList(DLinkList L) {
	DNode *p = L->next;
	while(p != NULL) {
		cout << p->data << " " ;
		p = p->next;
	}
	cout << endl;
}
//從后向前遍歷
void AfterFindList(DLinkList L) {
	DNode *p = L;
	while(p->next != NULL) {
		p = p->next;
	}
	
	while(p!=L) {
		cout << p->data << " " ;
		p = p->prior;
	}
	cout << endl;
}
 

int main() {
	
	DLinkList L;
	
	InitDLinkList(L);
	
	DList_TailInsert(L);
	
	PriorFindList(L);
	AfterFindList(L);
	
	DNode *p, *s;
	
	p = L;
	s = L;
	
	for(int i=0; i<=3; i++)	p = p->next;	//刪去第五個值 
	
	DeleteNextDNode(p);
	
	PriorFindList(L);
	AfterFindList(L);
	
	return 0;
} 

?

【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下),考研408之數據結構,數據結構,鏈表,408,考研

?

尾:

????????由于博主才疏學淺,總結的相關知識僅限于自我學習認知,若出現錯誤。望各位大神指點。在這里感謝各位。

? ? ? ? (由于學習的倉促,有些代碼未能完全實現以及部分磨塊的講解不充分;若后期實現該代碼,將會進行下一步的補充)文章來源地址http://www.zghlxwxcb.cn/news/detail-847001.html

到了這里,關于【玩轉408數據結構】線性表——雙鏈表、循環(huán)鏈表和靜態(tài)鏈表(線性表的鏈式表示 下)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

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

領支付寶紅包贊助服務器費用

相關文章

  • 數據結構_雙鏈表、循環(huán)鏈表、靜態(tài)鏈表

    數據結構_雙鏈表、循環(huán)鏈表、靜態(tài)鏈表

    目錄 1. 雙鏈表 1.1 雙鏈表的初始化 1.2 雙鏈表的插入操作 1.3 雙鏈表的刪除操作 1.4 雙鏈表的遍歷 2. 循環(huán)鏈表 2.1 循環(huán)單鏈表 2.2 循環(huán)雙鏈表 3. 靜態(tài)鏈表 4. 順序表和鏈表的比較 5. 相關練習 ????????單鏈表結點中只有一個指向其后繼的指針,使得單鏈表只能從頭結點依次順序

    2024年02月02日
    瀏覽(92)
  • 【數據結構與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。

    【數據結構與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。

    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 大家好,今天我們來學習數據結構中的順序表與鏈表!源碼在最后附上 首先我們先來認識一下 順序表 : ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? **如上圖所示:很多人會以為數組就是順序表,順序表就是數組,這

    2024年02月21日
    瀏覽(96)
  • 數據結構(二)——線性表(雙鏈表)

    數據結構(二)——線性表(雙鏈表)

    單鏈表:單鏈表結點中只有一個指向其后繼的指針,使得單鏈表只能從前往后依次遍歷,無法逆向檢索,有時候不太方便 雙鏈表的定義: 雙鏈表結點中有兩個指針prior和next,分別指向其直接前驅和直接后繼 表頭結點的prior域和尾結點的next域都是NULL。 雙鏈表結點類型描述如下

    2024年03月11日
    瀏覽(23)
  • 【數據結構】線性表和順序表

    【數據結構】線性表和順序表

    Yan-英杰的主頁 悟已往之不諫 知來者之可追 目錄 1.線性表 2.順序表 ??????? 2.1 靜態(tài)順序表 ??????? 2.2 動態(tài)順序表 ??????? 2.3移除元素 ??????? 線性表( linear list )是n個具有相同特性的數據元素的有限序列。 線性表是一種在實際中廣泛使用的數據結構,常見的線

    2023年04月08日
    瀏覽(94)
  • 【數據結構】線性表——帶頭雙向循環(huán)鏈表

    【數據結構】線性表——帶頭雙向循環(huán)鏈表

    帶頭雙向循環(huán)鏈表的優(yōu)點 1.支持任意位置時間復雜度為O(1)的插入和刪除。 2.按照需求申請釋放空間,無需擔心空間不夠用,無需擔心浪費。 3.帶頭可以省去鏈表為空時的判斷,可以使代碼更加簡約 帶頭雙向循環(huán)鏈表的缺點 1.不可以進行下標隨機訪問。 2.緩存利用率低 帶頭雙

    2024年02月03日
    瀏覽(14)
  • 數據結構: 線性表(帶頭雙向循環(huán)鏈表實現)

    數據結構: 線性表(帶頭雙向循環(huán)鏈表實現)

    之前一章學習了單鏈表的相關操作, 但是單鏈表的限制卻很多, 比如不能倒序掃描鏈表, 解決方法是在數據結構上附加一個域, 使它包含指向前一個單元的指針即可. 那么怎么定義數據結構呢? 首先我們先了解以下鏈表的分類 鏈表的結構非常多樣, 以下情況組合起來就有 8 中鏈表

    2024年02月14日
    瀏覽(26)
  • 【數據結構篇C++實現】- 線性表 - 順序表和鏈表

    【數據結構篇C++實現】- 線性表 - 順序表和鏈表

    友情鏈接:C/C++系列系統(tǒng)學習目錄 故事導入: 幼兒園放學時,一個班級的小朋友,一個跟著一個排隊出校,有一個打頭,有一個收尾,當中的小朋友每一個都知道他前面和后面的一個是誰,就如同一根線把他們串聯(lián)了起來。如此具有像線一樣的性質的表就叫線性表 線性表(

    2024年02月07日
    瀏覽(98)
  • 數據結構入門(C語言版)線性表帶頭雙向循環(huán)鏈表接口實現

    數據結構入門(C語言版)線性表帶頭雙向循環(huán)鏈表接口實現

    在上一篇博客我們講述了鏈表的概念和結構,還實現了無頭單向非循環(huán)鏈表接口寫法,那么這一章節(jié),我們來實現另一種常用的鏈表組成結構——帶頭雙向循環(huán)鏈表。 如果對前面的鏈表基本概念還是不了解,可以看作者的上一篇博客: 線性表中鏈表介紹及無頭單向非循環(huán)鏈

    2023年04月12日
    瀏覽(19)
  • 數據結構(王道)——線性表之靜態(tài)鏈表&順序表和鏈表的比較

    數據結構(王道)——線性表之靜態(tài)鏈表&順序表和鏈表的比較

    ? 如何定義一個靜態(tài)鏈表 ? ? 初始化靜態(tài)鏈表: ? 靜態(tài)鏈表的查找、插入、刪除 ? ? ? ? ? 創(chuàng): 銷: ? 增、刪: ? 查: ? 順序表、鏈表該如何選擇? ?

    2024年02月16日
    瀏覽(719)
  • 【數據結構初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實現)

    【數據結構初階】三、 線性表里的鏈表(無頭+單向+非循環(huán)鏈表 -- C語言實現)

    ========================================================================= 相關代碼gitee自取 : C語言學習日記: 加油努力 (gitee.com) ?========================================================================= 接上期 : 【數據結構初階】二、 線性表里的順序表(C語言實現順序表)-CSDN博客 ?=========================

    2024年02月08日
    瀏覽(35)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領取紅包

二維碼2

領紅包