29.數據結構 - 查找

查找在我們平時的使用中是非常頻繁的,查找的算法也比較多。查找算法的優劣將影響到計算機的使用效率,應根據應用場合選擇相應的查找算法

 

常見的查找方法有順序查找、折半查找、分塊查找、Hash表查找等等。效率最高,應用較多的是哈希表查找,我們也是重點學習,但是別的查找我們也要知道怎麼應用。

一.查找方法

1.順序查找

應用:順序查找適合於存儲結構爲順序存儲或鏈接存儲的線性表,最基本的查找技術

基本思想:順序查找也稱爲線形查找,屬於無序查找算法。從數據結構線形表的一端開始,順序掃描,依次將掃描到的結點關鍵字與給定值k相比較,若相等則表示查找成功;若掃描結束仍沒有找到關鍵字等於k的結點,表示查找失敗。

順序查找的時間複雜度爲O(n)。

 

明顯順序表的查找是非常費時的,在順序查找的基礎上進行優化就有了二分查找。

 

2.二分查找(折半查找)

應用:折半查找的前提條件是需要有序表順序存儲,對於靜態查找表,一次排序後不再變化,折半查找能得到不錯的效率。但對於需要頻繁執行插入或刪除操作的數據集來說,維護有序的排序會帶來不小的工作量,那就不建議使用

 

說明:元素必須是有序的,如果是無序的則要先進行排序操作。

基本思想:也稱爲是折半查找,屬於有序查找算法。用給定值k先與中間結點的關鍵字比較,中間結點把線形表分成兩個子表,若相等則查找成功;若不相等,再根據k與該中間結點關鍵字的比較結果確定下一步查找哪個子表,這樣遞歸進行,直到查找到或查找結束髮現表中沒有這樣的結點。

簡單理解其實就像電視中的看物品猜價格,先取個值,然後說大了小了,然後逐漸縮小範圍,得到最後的物品價格。

 

複雜度分析:最壞情況下,關鍵詞比較次數爲log2(n+1),且期望時間複雜度爲O(log2n)

例:

 

3.分塊查找

說明:分塊查找又稱索引順序查找,它是順序查找的一種改進方法。在塊內還能再使用折半查找,方法是靈活的。

算法思想:將n個數據元素"按塊有序"劃分爲m塊(m ≤ n)。每一塊中的結點不必有序,但塊與塊之間必須"按塊有序";即第1塊中任一元素的關鍵字都必須小於第2塊中任一元素的關鍵字;而第2塊中任一元素又都必須小於第3塊中的任一元素,……
算法流程:
step1 先選取各塊中的最大關鍵字構成一個索引表;
step2 查找分兩個部分:先對索引表進行二分查找或順序查找,以確定待查記錄在哪一塊中;然後,在已確定的塊中用順序法進行查找。

 

 

4.哈希表查找(效率高)

我們的重點來啦,哈希表查找,它的效率是比較高,應用的也比較多。

"直接定址"與"解決衝突"是哈希表的兩大特點

Hash是一種典型以空間換時間的算法

 

那麼哈希函數到底是什麼呢?

官方話語太難理解了,簡單說,我們通過一些算法和公式,得到許多的虛擬地址,我們查找的時候,只需要相同的公式就能找到該元素。但是有個問題就是不同元素通過一個公式計算的地址可能相同,就產生衝突

 

算法流程:

  1. hash函數的選取
  2. 用給定的哈希函數構造哈希表
  3. 根據選擇的衝突處理方法解決地址衝突
  4. 在哈希表的基礎上執行哈希查找

 

那麼我們的疑問就來了?哈希函數怎麼選?衝突怎麼解決?

直接舉個例子,例子講完了,所有的一些零碎的概念就能串起來了。

例:

k={23,34,14,38,46,16,68,15,07,31,26};

我們要存儲這麼一串數據,他的記錄數也就存儲個數n=11;那麼我們怎麼存呢,就需要構造一個hash函數。

 

常用的構造hash函數的方法有很多,直接地址法,平方取中法,疊加法,隨機函數法

保留除數法,用的最多的是保留除數法,那麼我們就選擇這個方法。

 

那麼什麼是保留除數法?

又稱質數除餘法,設Hash表空間長度爲m,選取一個不大於m的最大質數p,令:      H(key)=key%p。質數的選取(越大越好)

有了公式,但是我們的空間長度m和質數p我們都不知道。

m的選取涉及到一個概念表的裝填因子α

α=n/m,其中m爲表長,n爲表中記錄(存儲)個數。一般α在0.7~0.8之間,使表保持一定的空閒餘量,以減少衝突和聚積現象

根據存儲個數,得到M,根據m又可以得到質數p。

令裝填因子α=0.75,取表長m= én/αù =15。

用“保留餘數法”選取Hash函數(p=13): H(key)=key%13

根據這個公式我們就可以得到地址了,然後將數據存到指定的位置,但是這時候問題就來了,不同的數據卻計算出了相同的地址,也就是產生了衝突。

那麼怎麼解決衝突?

這裏主要用了兩種方法一個是開放地址法,一個是鏈地址的方法。

開放地址法:

 Hi=(H(key)+di)%m

原來hash函數基礎上,在它的附近找空間

但是出現一直衝突就聚集了,這種方法就不太靈了。

 

那就用鏈地址的方法

鏈地址法解決衝突的優點:無聚積現象;刪除表中記錄容易實現

那麼一個完整的hash表的建立過程就完成了。

特殊說明:

哈希表是一個在時間和空間上做出權衡的經典例子。如果沒有內存限制,那麼可以直接將鍵作爲數組的索引。那麼所有的查找時間複雜度爲O(1);如果沒有時間限制,那麼我們可以使用無序數組並進行順序查找,這樣只需要很少的內存。哈希表使用了適度的時間和空間來在這兩個極端之間找到了平衡。只需要調整哈希函數算法即可在時間和空間上做出取捨。

Hash是一種典型以空間換時間的算法

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章