国产精品天干天干,亚洲毛片在线,日韩gay小鲜肉啪啪18禁,女同Gay自慰喷水

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

十一、數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)——線性表和散列表

2023-03-19 23:26 作者:努力賺錢養(yǎng)朵朵  | 我要投稿


本章主要介紹線性表的鏈?zhǔn)酱鎯?、散列表的壓縮映射建立量數(shù)據(jù)類型間關(guān)系的作用。

一般條件下散列查找的性能可以媲美順序表的查找,即時間復(fù)雜度O(1)。


動態(tài)鏈表

(一)單鏈表結(jié)點的定義

單鏈表中每個節(jié)點都是一個節(jié)點,不僅要存儲元素值,還要存儲指向下一個元素的指針。可用如下類來表示這樣的節(jié)點:

(二)單鏈表的基本操作(插入、刪除、遍歷、查找)

①插入結(jié)點:

插入時需要先找到第p個節(jié)點的位置(0<=p<=n),因此最壞的時間復(fù)雜度為O(n)。

②刪除結(jié)點:

刪除時需要先找到第p個節(jié)點的位置(0<=p<=n),因此最壞的時間復(fù)雜度為O(n)。

③遍歷鏈表:

遍歷的時間復(fù)雜度為O(n)。

④查找結(jié)點:

查找第p個結(jié)點的時間復(fù)雜度為O(n)。

靜態(tài)鏈表

靜態(tài)鏈表中的指針不是通常意義的指針類型變量,而是存儲一個數(shù)組下標(biāo)的整型變量,通過它可以找到后繼節(jié)點在數(shù)組中的位置,其功能類似于真實的指針。

其結(jié)點定義如下:

但實際上為了簡便,編程上一般使用array<int,2>來作為一個結(jié)點的類型其中下標(biāo)為0的元素存儲節(jié)點的值,下標(biāo)為1的元素存儲結(jié)點的下一個結(jié)點地址。

在工程項目中,動態(tài)鏈表是最常見的鏈表的實現(xiàn)方法。但是在程序設(shè)計競賽或考試中,由于一般數(shù)據(jù)量是已知的,因此用靜態(tài)鏈表會易于編碼和查找。

雙向鏈表

雙向鏈表既可以向后遍歷,也可以向前遍歷。因此在單鏈表結(jié)點的基礎(chǔ)上增添一個指針域pre即可。雙向鏈表結(jié)點的定義如下:

C++標(biāo)準(zhǔn)庫中l(wèi)ist就是雙向鏈表,因此當(dāng)你獲取list中一個元素的迭代器時,可以快速找到其前驅(qū)和后繼。通常情況下,當(dāng)需要使用鏈表時,都可以用list容器實現(xiàn)相關(guān)功能

散列表

散列表提供一個數(shù)組,為每個可能的關(guān)鍵字保留一個位置,通過一個轉(zhuǎn)換函數(shù)將關(guān)鍵字轉(zhuǎn)換為一個它在數(shù)組中的下標(biāo),這個轉(zhuǎn)換函數(shù)稱為散列函數(shù)(或哈希函數(shù))。理想情況下,也能夠以O(shè)(1)的時間訪問散列表中的任意元素。

(一)散列函數(shù)

散列是一種壓縮映射,其核心思想是將一種類型的關(guān)鍵字通過一個函數(shù)轉(zhuǎn)換成一個整數(shù),使得這個整數(shù)能夠盡可能地表示這個關(guān)鍵字本身。這個函數(shù)稱為散列函數(shù)或哈希函數(shù),轉(zhuǎn)換成的整數(shù)稱為該關(guān)鍵字的散列值或哈希值。

常見的散列函數(shù)設(shè)計方法為

?除留余數(shù)法,即將key對一個指定的數(shù)字m(通常取散列表表長)取余數(shù)作為散列值,即:hash(key)%3Dkey%5C%20mod%5C%20m

(二)沖突

當(dāng)對于不同key得到同樣的哈希值時,稱之為沖突或碰撞。設(shè)計的散列函數(shù)應(yīng)當(dāng)盡可能避免沖突,為此散列表的表長通常設(shè)置為一個素數(shù)(例如1e9+7)。

補充:1e9+7是最小的10位素數(shù),對其取模后可以保證值在int(大概-2e9~2e9)范圍內(nèi)。

?常見的沖突解決方法有:

①開放定址法hash_i%3D(hash(key)%2Bd_i)%5C%20mod%5C%20m,其中hash(key)是散列函數(shù),m是散列表長,d_i是增量序列,i是已經(jīng)發(fā)生沖突的次數(shù)。增量序列可以有以下取法:

1)當(dāng)d_i%3D1%2C2%2C...%2Cm-1時,稱為線性探測法。

2)當(dāng)d_i%3D%5Cpm%201%5E2%2C%5Cpm%202%5E2%2C...%2C%5Cpm%20k%5E2(k%5Cleq%20m%2F2)時,稱為平方探測法。

②再散列法:定義多個散列函數(shù),若一個散列函數(shù)發(fā)生沖突,則逐一利用其他散列函數(shù)產(chǎn)生新的散列值,直到?jīng)_突不再發(fā)生。

③鏈地址法:將散列到同一位置得到所有元素保存在一個鏈表中。當(dāng)訪問一個元素時,先計算該元素的散列值,然后遍歷其對應(yīng)的單鏈表,查找相應(yīng)元素。當(dāng)需要使用散列表時,通常可以直接C++標(biāo)準(zhǔn)庫中的無序關(guān)聯(lián)容器(unordered_map、unordered_set),此時一般不需要實現(xiàn)這些解決沖突的辦法。

(三)自定義無序關(guān)聯(lián)容器的關(guān)鍵字哈希函數(shù)

無序關(guān)聯(lián)容器的關(guān)鍵字是限制類型的,當(dāng)需要將其他類型作為其關(guān)鍵字時,則要另外定義其哈希函數(shù)。無序容器在創(chuàng)建對象時,可以向它傳遞函數(shù)對象作為額外的參數(shù),這個函數(shù)對象定義了針對關(guān)鍵字類型對象的哈希函數(shù),它應(yīng)該返回一個整數(shù)值,建議返回long long類型

例如:自定義關(guān)鍵字是array<int,2>的unordered_map的哈希函數(shù)代碼模板

選用容器實現(xiàn)哈希表的原則

關(guān)鍵字能作為數(shù)組下標(biāo)且數(shù)據(jù)規(guī)模較小,使用數(shù)組(vector、array、bitset、C++內(nèi)置數(shù)組);

關(guān)鍵字不能作為數(shù)組下標(biāo),但可以直接作為無序關(guān)聯(lián)容器的鍵,用無序關(guān)聯(lián)容器;

關(guān)鍵字不能作為無序關(guān)聯(lián)容器的鍵,但能直接作為有序關(guān)聯(lián)容器的鍵,用有序關(guān)聯(lián)容器;

關(guān)鍵字不能直接做數(shù)組下標(biāo)、有/無序關(guān)聯(lián)容器的鍵,應(yīng)當(dāng)自定義該類型的默認哈希函數(shù)并使用無序關(guān)聯(lián)容器。

十一、數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)——線性表和散列表的評論 (共 條)

分享到微博請遵守國家法律
宁波市| 延寿县| 高密市| 安图县| 海口市| 惠东县| 分宜县| 平陆县| 游戏| 和顺县| 汉阴县| 北碚区| 芦溪县| 卓资县| 镇坪县| 登封市| 太原市| 稻城县| 兴化市| 崇信县| 玉山县| 永宁县| 平潭县| 安西县| 清丰县| 阿瓦提县| 许昌县| 天门市| 博乐市| 东至县| 奎屯市| 沙雅县| 新巴尔虎左旗| 长春市| 西林县| 平山县| 安义县| 遂溪县| 拉萨市| 论坛| 鹤岗市|