七大查找算法

  1. 順序查找
  2. 二分查找
  3. 插值查找
  4. 斐波那契查找
  5. 樹表查找
  6. 分塊查找
  7. 哈希查找

查找是在大量的信息中尋找一個特定的信息元素。在計算機應用中,查找是常用的基本運算,例如編譯程序中符號表的查找。

查找定義:根據給定的某個值,在查找表中確定一個其關鍵字等於給定值的數據元素(或記錄)。

查找算法分類:

1)靜態查找和動態查找:

注:靜態或者動態都是針對查找表而言的。

動態表指查找表中有刪除和插入操作的表。

2)無序查找和有序查找:

無序查找:被查找數列有序無序均可。
有序查找:被查找數列必須爲有序數列。

平均查找長度(Average Search Length, ASL):需和指定key進行比較得關鍵字的個數的期望值,稱爲查找算法在查找成功時的平均查找長度。

對於含有n個數據元素的查找表,查找成功的平均查找長度爲:ASL=Pi*Ci的和。

Pi:查找表中第i個數據元素的概率。
Ci:找到第i個數據元素時已經比較過的次數。

1. 順序查找

說明:順序查找適合於存儲結構爲順序存儲或鏈接存儲的線性表。

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

複雜度分析:

查找成功時的平均查找長度爲:(假設每個數據元素的概率相等)ASL = (n+1)/2;

當查找不成功時,需要n+1次比較,時間複雜度爲O(n);

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

2. 二分查找

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

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

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

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

3. 插值查找

在介紹插值查找之前,首先考慮一個新問題,爲什麼上述算法一定要是折半,而不是折四分之一或者折更多呢?

打個比方,在英文字典裏面查“apple”,你下意識翻開字典是翻前面的書頁還是後面的書頁呢?如果再讓你查“zoo”,你又怎麼查?很顯然,這裏你絕對不會是從中間開始查起,而是有一定目的的往前或往後翻。

同樣的,比如要在取值範圍1 ~ 10000 之間 100 個元素從小到大均勻分佈的數組中查找5, 我們自然會考慮從數組下標較小的開始查找。

經過以上分析,折半查找這種查找方式,不是自適應的(也就是說是傻瓜式的)。二分查找中查找點計算如下:

  mid=(low+high)/2, 即 mid=low+1/2*(high-low);

通過類比,我們可以將查找的點改進爲如下:

  mid=low+(key-a[low])/(a[high]-a[low])*(high-low),

也就是將上述的比例參數1/2改進爲自適應的,根據關鍵字在整個有序表中所處的位置,讓mid值的變化更靠近關鍵字key,這樣也就間接地減少了比較次數。

基本思想:基於二分查找算法,將查找點的選擇改進爲自適應選擇,可以提高查找效率。當然,差值查找也屬於有序查找。

注:對於表長較大,而關鍵字分佈又比較均勻的查找表來說,插值查找算法的平均性能比折半查找要好的多。反之,數組中如果分佈非常不均勻,那麼插值查找未必是很合適的選擇。

複雜度分析:查找成功或者失敗的時間複雜度均爲O(log2(log2n))

4. 斐波那契查找

在介紹斐波那契查找算法之前,我們先介紹一下很它緊密相連並且大家都熟知的一個概念——黃金分割。

黃金比例又稱黃金分割,是指事物各部分間一定的數學比例關係,即將整體一分爲二,較大部分與較小部分之比等於整體與較大部分之比,其比值約爲1:0.618或1.618:1。

0.618被公認爲最具有審美意義的比例數字,這個數值的作用不僅僅體現在諸如繪畫、雕塑、音樂、建築等藝術領域,而且在管理、工程設計等方面也有着不可忽視的作用。因此被稱爲黃金分割。

大家記不記得斐波那契數列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…….(從第三個數開始,後邊每一個數都是前兩個數的和)。然後我們會發現,隨着斐波那契數列的遞增,前後兩個數的比值會越來越接近0.618,利用這個特性,我們就可以將黃金比例運用到查找技術中。

基本思想:也是二分查找的一種提升算法,通過運用黃金比例的概念在數列中選擇查找點進行查找,提高查找效率。同樣地,斐波那契查找也屬於一種有序查找算法。

相對於折半查找,一般將待比較的key值與第mid=(low+high)/2位置的元素比較,比較結果分三種情況:

 1)相等,mid位置的元素即爲所求
 2)>,low=mid+1;
 3)<,high=mid-1。

斐波那契查找與折半查找很相似,他是根據斐波那契序列的特點對有序表進行分割的。他要求開始表中記錄的個數爲某個斐波那契數小1,及n=F(k)-1;

開始將k值與第F(k-1)位置的記錄進行比較(及mid=low+F(k-1)-1),比較結果也分爲三種

1)相等,mid位置的元素即爲所求

2)>,low=mid+1,k-=2;

說明:low=mid+1說明待查找的元素在[mid+1,high]範圍內,k-=2 說明範圍[mid+1,high]內的元素個數爲n-(F(k-1))= Fk-1-F(k-1)=Fk-F(k-1)-1=F(k-2)-1個,所以可以遞歸的應用斐波那契查找。

3)<,high=mid-1,k-=1。
說明:low=mid+1說明待查找的元素在[low,mid-1]範圍內,k-=1 說明範圍[low,mid-1]內的元素個數爲F(k-1)-1個,所以可以遞歸 的應用斐波那契查找。

複雜度分析:最壞情況下,時間複雜度爲O(log2n) ,且其期望複雜度也爲O(log2n)

5. 樹表查找

5.1 最簡單的樹表查找算法——二叉樹查找算法。

基本思想:二叉查找樹是先對待查找的數據進行生成樹,確保樹的左分支的值小於右分支的值,然後在就行和每個節點的父節點比較大小,查找最適合的範圍。 這個算法的查找效率很高,但是如果使用這種查找方法要首先創建樹。

二叉查找樹(BinarySearch Tree,也叫二叉搜索樹,或稱二叉排序樹Binary Sort Tree)或者是一棵空樹,或者是具有下列性質的二叉樹:

1)若任意節點的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;

2)若任意節點的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;

3)任意節點的左、右子樹也分別爲二叉查找樹。

二叉查找樹性質:對二叉查找樹進行中序遍歷,即可得到有序的數列。

不同形態的二叉樹如圖所示:

這裏寫圖片描述

複雜度分析:它和二分查找一樣,插入和查找的時間複雜度均爲O(log2n) ,但是在最壞的情況下仍然會有O(n)的時間複雜度。原因在於插入和刪除元素的時候,樹沒有保持平衡(比如,我們查找上圖(b)中的“93”,我們需要進行n次查找操作)。我們追求的是在最壞的情況下仍然有較好的時間複雜度,這就是平衡查找樹設計的初衷。

基於二叉查找樹進行優化,進而可以得到其他的樹表查找算法,如平衡樹、紅黑樹等高效算法。

5.2 平衡查找樹之2-3查找樹(2-3 Tree)

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