資料結構與演算法之字典與集合

2022-10-09 09:24:15 字數 4334 閱讀 9472

為什麼需要字典?

在我們日常生活中,字典關係處處可見,比如上學時給每個同學的學號,工作時給每位同事的工號等,如果沒有這樣的乙個關係對映,那麼在查詢時將會消耗多餘時間,而這是難接受的一種現象。在計算機中,資料的儲存與檢索操作很頻繁,迭代方式效率低,所以想到能不能在檢索資料結構時,所提供的關鍵字(或關鍵碼)作為下標,然後所需要得到的資訊作為儲存內容,(關鍵碼->儲存內容)這樣的下標對映如果存在,那麼我們通過關鍵碼去拿資訊將會是常量時間。

字典分類

靜態字典:只用建立一次,建立之後,字典內容和結構都不再變化,主要操作是檢索。

動態字典:在初始建立之後,字典的內容和結構將一直處於變動之中。除了檢索操作之外,重要的還有資料項的插入和刪除。

字典怎麼實現?

從結構上來,字典就是key-value結構的匯集,可以使用python中的乙個tuple(二元組)來定義字典中元素的結構,或者定義乙個結點類,裡面有key或value兩個屬性來定義字典中元素的結構。字典可以通過其他一些資料結構作為基礎來實現。比如順序表。

順序表實現字典

實現**:略

實現總結:實現比較簡單,就是乙個陣列,陣列裡的每個元素是乙個二元組,[(key1, value1),(key2, value2)...],類似此種結構,檢索時,只能通過給定的關鍵字來遍歷陣列然後對比key來查詢元素,刪除元素時也需要先遍歷再刪除並移動元素。檢索、刪除操作效率不高,但實現簡單。

順序表實現字典2(有序順序表和二分查詢)

以上通過順序表來實現字典時,檢索、刪除不高的原因在於字典中的二元組儲存是亂的,如果二元組按順序儲存,那麼當我們需要定位某個元素(關鍵碼)時,就可以通過二分查詢的演算法來快速定位。

實現**:略

實現總結:通過有序的順序表來實現字典,在檢索時速度快,為o(logn)的時間複雜度。對於插入、刪除元素時,檢索到要插入位置與刪除元素的位置時是o(logn)時間,但是插入元素後或刪除元素後都要維護字典原有的結構,都需要去移動元素,所以時間還是o(n)。

順序表實現字典適應場景:字典規模比較小,且不常進行動態變化的一些字典。

雜湊表實現字典

雜湊:將關鍵字key轉換為儲存資料的位址(下標)的方式叫做雜湊。此種轉換函式稱為雜湊函式或雜湊(hash)函式。

前面提過,最快能訪問到關鍵字對應的資訊的方法就是將關鍵字作為位址下標,那麼我們在獲取資料的時候就是o(1)時間。而關鍵字作為位址下標的操作稱之為雜湊。

雜湊技術的實現:我們將雜湊函式記做h(),對於任何乙個key都有對應的下標index=h(key),而對應的下標是我們已經選定的一塊儲存區域位址,比如0-19,對於大資料量的key,我們都需要將h(key)對映到(0-19)這個範圍內。這是一種大範圍到小範圍的對映,肯定會產生不同的key對映到同乙個下標的情況,這種情況稱之為雜湊衝突:當乙個雜湊表中負載因子越大,發生雜湊衝突的機率也越大,而且衝突具有不知何時發生的不確定性與隨時都可能發生的確定性。所以必須要有處理雜湊衝突的方法。

雜湊函式的設計:雜湊函式的選擇好壞決定於雜湊衝突發生的機率,雜湊函式選擇需要遵循以下幾點:

1、函式能將關鍵碼對映到儲存位址區間(值域index)中盡可能大的部分,也就是說雜湊函式最好能將儲存位址區間index裡的每個下標都能一一對映到,避免有的下標對映不上,浪費。

2、儲存位址區間中的雜湊值應該均勻分布。

3、函式簡單

對於整數的關鍵碼若干雜湊方法:數字分析法(就是選取整數關鍵碼的某些位置的數字作為下標),摺疊法(將數字分為幾段,並將它們進行運算,運算的結果去掉進製等)、中平方法(求出關鍵碼的平方,然後取出中間的幾位作為雜湊值)

常用雜湊函式:

1、除餘法:將整數值除於儲存位址區間index的範圍值,得到的餘數作為雜湊位址,比如一段整數值為5,7,11,44,將它們除以index範圍值為10(index=[0-9]),得到的雜湊位址為5/10=5,7/10=7,11/10=1,44/10=4 => 5,7,1,4

2、基數轉換法:將關鍵碼看做r進製的數,然後將關鍵碼轉換為十進位制或二進位制

3、非整數的轉換:先轉換成整數,然後使用基數轉換法或除餘法進行得到雜湊位址

衝突消解機制

衝突的內消解:開位址技術:

內消解:在儲存區的內部解決衝突問題。

開位址法:基本思想是:當遇到衝突時,為所衝突的元素再查詢乙個合適的位置,查詢的過程稱之為探查方式。

探查方式分為兩種:

1、線性探查:當遇到衝突時,為衝突元素查詢合適位置時,是一步步向前後向後探測,每次探測距離是線性的。

2、雙雜湊探查:當遇到衝突時,為衝突元素查詢合適位置時,再進行一次雜湊來確定新的位置。

衝突的外消解:鏈位址技術

外消解的方法有兩種:

1、溢位區方法:另外設定乙個溢位區,當發生衝突時將元素儲存在溢位區,在溢位區裡面的元素順序儲存,當在雜湊表中找不到元素時,就到溢位區中查詢,但是一旦溢位區擴大,字典的效能將趨向於線性。

2、桶雜湊(鏈位址法、拉鍊法):就是在雜湊表中不直接儲存關鍵碼對應的資料,而是儲存了另乙個鍊錶結構,鍊錶結構是另乙個表,裡面存的是衝突關鍵碼的所有結點。桶雜湊可用於大型字典,用於組織大量的資料,包括外存檔案等。

集合:個體的匯集。在數學中集合是乙個很重要的概念,它有三種特性:

1、確定性:集合中的元素是明確的

2、互異性:集合中任何兩個元素都是不相同的。

3、無序性

集合有三種重要的運算操作應用很廣:

求並集:比如兩個集合s與t,s與t的並集中的元素是s的元素或者是t的元素。

求交集:比如兩個集合s與t,s與t的交集中的元素既是s的元素,也是t的元素。

求差集:比如兩個集合s與t,s與t的差集中的元素表示僅屬於s不屬於t的元素,t與s的差集表示僅屬於t不屬於s的元素。

集合的實現

集合是一種匯集的資料結構,可以使用一些匯集型的資料結構比如順序表、鍊錶或字典。

簡單順序表實現集合

總結:一些基本的操作,比如判斷元素是否在集合中,往集合插入元素(保證唯一性),刪除某個元素都是o(n)時間,重要操作,求並交差集為o(m*n)時間。效能上較差。

排序順序表實現集合

總結:相較於簡單順序表,檢索方面的效能有所提公升,為o(logn)時間,重要操作,求並交差集為o(m+n)時間。效能上有較大提公升

雜湊表實現集合

效能:在雜湊表還沒有較大衝突的情況下,各種操作都很高效。求並差交集也有o(m+n)的高效時間。

為什麼用雜湊表實現集合比較好?

相比最高效,將集合中的元素作為雜湊表中的關鍵碼來使用,並通過雜湊函式進行轉換為位址下標,就能通過常量時間來訪問集合元素了。

位向量實現集合

有乙個集合的總集u,比如u=,我們所使用的任何乙個集合si都是屬於u的子集,比如s1=,那麼s1的位向量表示則為s=11100000,s2=,則s2=01110000,等等情況,1和0表示的含義在於,1代表此集合s元素在u中,0代表不在u中。

位向量使用集合時,操作代價基於集合u的大小度量,因為無論是空集,它的表示長度還是8位,空集=00000000。在需要處理的是u的一些子集時,且u的規模不是很大的情況下這種實現方式比較適用。

擴充套件:平均檢索長度:在一次完整檢索中比較關鍵碼的的平均次數,通常稱為平均檢索長度(asl)。

索引:字典是兩種功能的統一,1、作為一種資料儲存結構,支援在字典裡儲存一批資料項。2、提供支援資料檢索功能,設法維護從關鍵碼找到相關資料的聯絡資訊。第二點也稱之為索引,其存在的目的就是為檢索服務。索引所做的事就是要實現從關鍵碼到資料儲存位置的對映。

負載因子:雜湊表中當時的實際資料項樹/雜湊表的基本儲存區能容納的元素個數,比如雜湊表所儲存的元素為7個,雜湊表儲存區能存下10個元素,那麼負載因子就是7/10=0.7。

總結

1、字典是一種常用的資料結構,字典的基礎結構就是key-value的對映,因此字典也被稱為對映。

2、用雜湊技術來實現字典,可以將關鍵碼轉換為位址下標,將訪問時間達到常量級別。

3、用雜湊實現字典時,雜湊是大範圍到小範圍的對映,所以會產生雜湊衝突,雜湊衝突的方式有內消解與外消解方法,內消解是開位址法,在發生衝突時,為所衝突元素再找到乙個插入位置;外消解法包括溢位表與桶雜湊法,在發生衝突時,將元素不直接儲存在已衝突的雜湊表中。

4、集合就是一批元素的匯集,使用雜湊技術來實現集合是最高效的。在特定場景下,使用位向量方式使用集合也是一種高效的手段。

5、基於雜湊實現的字典雖然效率高,但是沒有確定性的效率保證,因為一旦資料量增大,雜湊字典的效率逐步下降。所以對於實現字典還有更多可**的方式,樹形結構來實現字典是其中一種,可以參考這篇博文。二叉排序樹、平衡二叉樹、多分支排序樹、b樹、b+樹

資料結構與演算法 字典樹

字典樹又稱單詞查詢樹,trie樹,是一種樹形結構,是一種雜湊樹的變種。典型應用是用於統計,排序和儲存大量的字串 但不僅限於字串 所以經常被搜尋引擎系統用於文字詞頻統計。它的優點是 利用字串的公共字首來減少查詢時間,最大限度地減少無謂的字串比較,查詢效率比雜湊樹高。字典樹 桀驁 2018 8 3 in...

js資料結構與演算法 字典

一 字典的主要操作 字典的key是不能重複的 value是可以重複的,重複後面的會覆蓋前面的 二 實現 class dictionary 儲存字典key value 是否有key has key 設定key value set key,value 刪除key delete key return fa...

javascript資料結構與演算法 集合

集合是由一組無序且唯一 即不能重複 的項組成的。類似於一種特殊的陣列,因為無序所以不能通過索引進行訪問,不能重複意味著相同的元素在聽乙個集合裡面是只能存在乙份。封裝乙個集合類 在集合內部是不需要再次進行內部類的。function set 方法 常見的方法 add value 向集合新增乙個新的項。r...