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

算法競賽基礎(chǔ):C++雙向鏈表的結(jié)構(gòu)和實(shí)現(xiàn)(普通鏈表、List、靜態(tài)鏈表)

這篇具有很好參考價(jià)值的文章主要介紹了算法競賽基礎(chǔ):C++雙向鏈表的結(jié)構(gòu)和實(shí)現(xiàn)(普通鏈表、List、靜態(tài)鏈表)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

算法競賽基礎(chǔ):雙向鏈表

本文將會介紹在算法競賽中雙向鏈表的幾種使用方式,適合有一定基礎(chǔ)的人閱讀。

雙向鏈表的結(jié)構(gòu)

一般來說,普通的鏈表結(jié)構(gòu)是這樣的:

struct node {
	int num;
	node *next; 
}

next指針指向下一個(gè)鏈表,這樣的結(jié)構(gòu)只能夠支持單向查詢。

雙向鏈表,顧名思義,就是可以支持雙向的訪問和查詢。

也就是這樣的:

struct node {
	int num;
	node *l, *r;
}

這種鏈表為訪問前后的元素提供的很大的便利性。

C++的STL模板中也有類似的結(jié)構(gòu):
List

list<int> lis;

List是連續(xù)的容器,而vector是非連續(xù)的容器,即list將元素存儲在連續(xù)的存儲器中,而vector存儲在不連續(xù)的存儲器中。

向量(vector)中間的插入和刪除是非常昂貴的,因?yàn)樗枰罅康臅r(shí)間來移動所有的元素。鏈表克服了這個(gè)問題,它是使用list容器實(shí)現(xiàn)的。

List支持雙向,并為插入和刪除操作提供了一種有效的方法。

在列表中遍歷速度很慢,因?yàn)榱斜碓厥前错樞蛟L問的,而vector支持隨機(jī)訪問。

列表模板

示例

#include<iostream>
#include<list>
using namespace std;
int main()
{
   list<int> l;
}

它創(chuàng)建一個(gè)空的整數(shù)類型值列表。

列表也可以使用參數(shù)初始化。

示例

#include<iostream>
#include<list>
using namespace std;
int main()
{
   list<int> l{1,2,3,4};
}

列表可以通過兩種方式初始化。

示例

list<int>  new_list{1,2,3,4};
or
list<int> new_list = {1,2,3,4};

list支持的操作有以下這些:

方法 描述
insert() 它將新元素插入到迭代器指向的位置之前。
push_back() 它在容器的末尾添加了一個(gè)新元素。
push_front() 它在前面增加了一個(gè)新元素。
pop_back() 刪除最后一個(gè)元素。
pop_front() 刪除第一個(gè)元素。
empty() 它檢查列表是否為空。
size() 它查找列表中存在的元素?cái)?shù)。
max_size() 它找到列表的最大大小。
front() 它返回列表的第一個(gè)元素。
back() 它返回列表的最后一個(gè)元素。
swap() 當(dāng)兩個(gè)列表的類型相同時(shí),它將交換兩個(gè)列表。
reverse() 它反轉(zhuǎn)了列表的元素。
sort() 它以遞增的順序?qū)α斜碇械脑剡M(jìn)行排序。
merge() 它合并兩個(gè)排序的列表。
splice() 它將新列表插入到調(diào)用列表中。
unique() 它從列表中刪除所有重復(fù)的元素。
resize() 它更改列表容器的大小。
assign() 它將一個(gè)新元素分配給列表容器。
emplace() 它將在指定位置插入一個(gè)新元素。
emplace_back() 它將在容器的末尾插入一個(gè)新元素。
emplace_front() 它將在列表的開頭插入一個(gè)新元素。
erase() 刪除這個(gè)元素

但是這種結(jié)構(gòu)往往在大量數(shù)據(jù)的情況下會超時(shí)。我們需要一種更加有效的方式,通常,我們選擇空間換時(shí)間,因此靜態(tài)鏈表通常是更好的選擇,接下來介紹一種靜態(tài)雙向循環(huán)鏈表在競賽中實(shí)現(xiàn)的方式。

競賽方式實(shí)現(xiàn)

思路是這樣的:

要實(shí)現(xiàn)一個(gè)靜態(tài)雙向循環(huán)鏈表,需要模擬一個(gè)左右指針,在這里,我們選擇花費(fèi)大量空間去用數(shù)組的下標(biāo)代替指針和對應(yīng)的值:

#include <bits/stdc++.h>
using namespace std;

const int MAX_N 1e5 + 10;

struct node {
	int l, r;
	int key;
} arr[MAX_N] = {0};

其中,lr分別表示上一個(gè)和下一個(gè)元素的數(shù)組下標(biāo)。

插入操作

插入操作的思路很簡單:
先將新元素的lr指向左右兩個(gè)元素。
再分別讓左右兩個(gè)元素的rl分別指向新元素本身;


//ll:左元素,rr:右元素, new:新元素
void add(int ll, int rr, int new) {
	arr[new].l = ll;
	arr[new].r == rr;
	arr[ll].r == new;
	arr[rr].l == new;
}

這不是一種唯一的實(shí)現(xiàn)方式,其中的參數(shù)和需求都可以根據(jù)具體情況改變。

刪除操作

刪除操作提供兩種思路:

  • 第一種與插入操作類似,實(shí)現(xiàn)元素的刪除
  • 第二種更加快速,通過在節(jié)點(diǎn)種的key值,去判斷是否輸出(如果要求輸出鏈表的話)

第一種方式:

void del(int target) {
	int l, r;
	l = arr[target].l;
	r = arr[target].r;

	arr[l].r = r;
	arr[r].l = l;
	

第二種方式:

void del(int target) {
	arr[target].key = 0; //在對鏈表元素進(jìn)行操作時(shí),檢測其key值的真值,如果為0,直接不對其進(jìn)行操作
}

第二種方式雖然沒有改變lr的值,但是也能夠?qū)崿F(xiàn)鏈表訪問機(jī)制的修改而且還支持?jǐn)?shù)據(jù)恢復(fù),相當(dāng)好用。

查找操作

這種方式是基于上面刪除操作時(shí)的第二種方式實(shí)現(xiàn)的:

bool find(int target) {
	return arr[target].key == 1;
}

因?yàn)檫@種特殊的鏈表結(jié)構(gòu)支持隨機(jī)訪問(正常的鏈表結(jié)構(gòu)是不支持的),所以查找操作變成檢測對應(yīng)元素的鍵值是否有效,如果有效,返回一個(gè)真值。

遍歷操作

以輸出全部數(shù)值為例:

這里值得一提的是,如果按照這種上文所述的方式去建立雙向鏈表的話,你會發(fā)現(xiàn)沒有頭結(jié)點(diǎn)。

具體原因是由于開辟第一個(gè)結(jié)點(diǎn)時(shí),也就是數(shù)組下標(biāo)為1的時(shí)候,結(jié)構(gòu)體中的lr指向的是1本身,那這個(gè)時(shí)候如果再多插入幾個(gè)結(jié)點(diǎn),最后一個(gè)結(jié)點(diǎn)的r會指向1,1的l會指向最后一個(gè)結(jié)點(diǎn),這樣一來,當(dāng)你在1之前插入結(jié)點(diǎn)時(shí),按理來說頭節(jié)點(diǎn)會變成新插入的結(jié)點(diǎn),但由于缺少一個(gè)指向頭節(jié)點(diǎn)的指針而丟失鏈表的頭,這顯然是我們不想看到的。

解決方法也很簡單,我們在數(shù)組下標(biāo)為0的位置創(chuàng)建一個(gè)結(jié)點(diǎn)作為虛擬頭結(jié)點(diǎn),當(dāng)在真正的頭結(jié)點(diǎn)之前插入新的結(jié)點(diǎn)時(shí),這時(shí)候新結(jié)點(diǎn)會在0和頭節(jié)點(diǎn)之間,當(dāng)我們需要訪問頭節(jié)點(diǎn)的時(shí)候,通過0去訪問就可以了。

下面是建立的虛擬頭節(jié)點(diǎn)0之后的遍歷輸出操作:文章來源地址http://www.zghlxwxcb.cn/news/detail-821338.html

void bs() {
	// from left to right
	for (int i = arr[0].r; i; i = arr[i].r) {
		cout << arr[i] << " ";
	}

到了這里,關(guān)于算法競賽基礎(chǔ):C++雙向鏈表的結(jié)構(gòu)和實(shí)現(xiàn)(普通鏈表、List、靜態(tài)鏈表)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu):雙向鏈表的實(shí)現(xiàn)(C實(shí)現(xiàn))

    數(shù)據(jù)結(jié)構(gòu):雙向鏈表的實(shí)現(xiàn)(C實(shí)現(xiàn))

    個(gè)人主頁 : 個(gè)人主頁 個(gè)人專欄 : 《數(shù)據(jù)結(jié)構(gòu)》 《C語言》 本篇博客,將要實(shí)現(xiàn)的是 帶頭雙向循環(huán)鏈表 ,該結(jié)構(gòu)實(shí)現(xiàn)尾插,尾刪只需要O(1)的時(shí)間復(fù)雜度。 其結(jié)構(gòu)如下所示: 既然要實(shí)現(xiàn)的鏈表是雙向循環(huán)的,那么對于指針域,我們就需要 指向節(jié)點(diǎn)上一個(gè)的指針 和 指向節(jié)點(diǎn)

    2024年02月14日
    瀏覽(22)
  • 【數(shù)據(jù)結(jié)構(gòu)】—帶頭雙向循環(huán)鏈表的實(shí)現(xiàn)(完美鏈表)

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

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

    2024年01月25日
    瀏覽(18)
  • 【數(shù)據(jù)結(jié)構(gòu)】雙向鏈表的增刪查改(C 代碼實(shí)現(xiàn))

    【數(shù)據(jù)結(jié)構(gòu)】雙向鏈表的增刪查改(C 代碼實(shí)現(xiàn))

    引入雙向鏈表:關(guān)于單鏈表的問題與討論 單鏈表存在的毛?。?因?yàn)閱捂湵?只能單向 遍歷鏈表, 對于 前插 這個(gè)操作,單鏈表必 須得找到所需前插節(jié)點(diǎn)位置的前一個(gè) ,那么這時(shí)就得 從頭指針重新遍歷一次 鏈表,會造成時(shí)間復(fù)雜度大大增加。 沒有頭節(jié)點(diǎn)(哨兵位)無法刪除

    2024年02月08日
    瀏覽(99)
  • 青島大學(xué)_王卓老師【數(shù)據(jù)結(jié)構(gòu)與算法】Week04_04_雙向鏈表的插入_學(xué)習(xí)筆記

    青島大學(xué)_王卓老師【數(shù)據(jù)結(jié)構(gòu)與算法】Week04_04_雙向鏈表的插入_學(xué)習(xí)筆記

    本文是個(gè)人學(xué)習(xí)筆記,素材來自青島大學(xué)王卓老師的教學(xué)視頻。 一方面用于學(xué)習(xí)記錄與分享,另一方面是想讓更多的人看到這么好的《數(shù)據(jù)結(jié)構(gòu)與算法》的學(xué)習(xí)視頻。 如有侵權(quán),請留言作刪文處理。 課程視頻鏈接: 數(shù)據(jù)結(jié)構(gòu)與算法基礎(chǔ)–第04周04–2.5.4雙向鏈表2–雙向鏈表

    2024年02月12日
    瀏覽(22)
  • 【數(shù)據(jù)結(jié)構(gòu)】鏈表的分類和雙向鏈表

    【數(shù)據(jù)結(jié)構(gòu)】鏈表的分類和雙向鏈表

    本篇是基于上篇單鏈表所作,推薦與上篇配合閱讀,效果更加 http://t.csdnimg.cn/UhXEj 鏈表的結(jié)構(gòu)非常多樣,以下情況組合起來就有8種(2 x 2 x 2)鏈表結(jié)構(gòu): 我們一般叫這個(gè)頭為哨兵位 我們上回講的單鏈表就是不帶頭單項(xiàng)不循環(huán)鏈表。 今天我們要講帶頭雙向循環(huán)的鏈表。 不過

    2024年01月25日
    瀏覽(26)
  • 數(shù)據(jù)結(jié)構(gòu)_鏈表_雙向循環(huán)鏈表的初始化、插入、刪除、修改、查詢打?。ɑ贑語言實(shí)現(xiàn))

    數(shù)據(jù)結(jié)構(gòu)_鏈表_雙向循環(huán)鏈表的初始化、插入、刪除、修改、查詢打?。ɑ贑語言實(shí)現(xiàn))

    版本: 2024年4月26日 V1.0 發(fā)布于博客園 目錄 目錄 雙向循環(huán)鏈表公式 初始化雙向循環(huán)鏈表 構(gòu)建雙向循環(huán)鏈表結(jié)點(diǎn) 創(chuàng)建一個(gè)空鏈表(僅頭結(jié)點(diǎn)) 創(chuàng)建一個(gè)新結(jié)點(diǎn) 插入數(shù)據(jù) 頭插 中插 尾插 刪除數(shù)據(jù) 頭刪 中刪 尾刪 查詢打印數(shù)據(jù) 遍歷打印 測試 測試結(jié)果: 完整代碼 DoubleCirLList.h

    2024年04月27日
    瀏覽(36)
  • 數(shù)據(jù)結(jié)構(gòu)---雙向鏈表的基本操作

    頭插法 遍歷鏈表 尾插法 頭刪法 尾刪法 按位置插入數(shù)據(jù) 按位置刪除數(shù)據(jù) dooublelinklist.c doublelinklist.h doublemain.c

    2024年02月22日
    瀏覽(96)
  • 探索數(shù)據(jù)結(jié)構(gòu):雙向鏈表的靈活優(yōu)勢

    探索數(shù)據(jù)結(jié)構(gòu):雙向鏈表的靈活優(yōu)勢

    ?? 歡迎大家來到貝蒂大講堂?? ????養(yǎng)成好習(xí)慣,先贊后看哦~???? 所屬專欄:數(shù)據(jù)結(jié)構(gòu)與算法 貝蒂的主頁:Betty’s blog 前面我們學(xué)習(xí)了單鏈表,它解決了順序表中插入刪除需要挪動大量數(shù)據(jù)的缺點(diǎn)。但同時(shí)也有仍需改進(jìn)的地方,比如說:我們有時(shí)候需要尋找某個(gè)節(jié)點(diǎn)

    2024年03月16日
    瀏覽(24)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】之雙向鏈表及其實(shí)現(xiàn)!

    【數(shù)據(jù)結(jié)構(gòu)與算法】之雙向鏈表及其實(shí)現(xiàn)!

    ? ????????????????????????????????????????????????? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ?個(gè)人主頁:秋風(fēng)起,再歸來~ ? ?????????????????????????????????????????? ? ? ? ? ? ? ?? ???? ? ? ? ? ? ? ???? ? ? ? ? ? 數(shù)據(jù)結(jié)構(gòu)與

    2024年04月23日
    瀏覽(27)
  • 【數(shù)據(jù)結(jié)構(gòu)和算法】使用數(shù)組的結(jié)構(gòu)實(shí)現(xiàn)鏈表(單向或雙向)

    【數(shù)據(jù)結(jié)構(gòu)和算法】使用數(shù)組的結(jié)構(gòu)實(shí)現(xiàn)鏈表(單向或雙向)

    上文我們通過結(jié)構(gòu)體的結(jié)構(gòu)實(shí)現(xiàn)了隊(duì)列 、以及循環(huán)隊(duì)列的實(shí)現(xiàn),我們或許在其他老師的教學(xué)中,只學(xué)到了用結(jié)構(gòu)體的形式來實(shí)現(xiàn)鏈表、隊(duì)列、棧等數(shù)據(jù)結(jié)構(gòu),本文我想告訴你的是,我們 可以使用數(shù)組的結(jié)構(gòu)實(shí)現(xiàn)鏈表、單調(diào)棧、單調(diào)隊(duì)列 目錄 前言 一、用數(shù)組結(jié)構(gòu)的好處 1.數(shù)

    2024年01月20日
    瀏覽(96)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包