數據結構中的查找


參考: https://www.cnblogs.com/yw09041432/p/5908444.html

七大查找算法:

  • 1. 順序查找順序查找適合於存儲結構為順序存儲或鏈接存儲的線性表,時間復雜度為O(n)
  • 2. 二分查找元素必須是有序的,如果是無序的則要先進行排序操作。
  • 3. 插值查找基於二分查找算法,將查找點的選擇改進為自適應選擇,mid=low+(key-a[low])/(a[high]-a[low])*(high-low),適合表長較大,而關鍵字分布又比較均勻的查找表
  • 4. 斐波那契查找二分查找的一種提升算法,通過運用黃金比例的概念在數列中選擇查找點進行查找,要求開始表中記錄的個數為某個斐波那契數小1,及n=F(k)-1;開始將k值與第F(k-1)位置的記錄進行比較(及mid=low+F(k-1)-1)。如果>,low=mid+1,k-=2;如果<,high=mid-1,k-=1。

5. 樹表查找

(1)二叉查找樹與平衡二叉樹(AVL)

(2)平衡查找樹之2-3查找樹(2-3 Tree)其實和B樹很像,只不過限定了m=3,節點只有1個或者2個key

效率:

(3)平衡查找樹之紅黑樹(Red-Black Tree)

  2-3樹實現起來比較復雜,於是就有了一種簡單實現2-3樹的數據結構,即紅黑樹(Red-Black Tree)。

   基本思想:紅黑樹的思想就是對2-3查找樹進行編碼,尤其是對2-3查找樹中的3-nodes節點添加額外的信息。紅黑樹中將節點之間的鏈接分為兩種不同類型,紅色鏈接,他用來鏈接兩個2-nodes節點來表示一個3-nodes節點。黑色鏈接用來鏈接普通的2-3節點。特別的,使用紅色鏈接的兩個2-nodes來表示一個3-nodes節點,並且向左傾斜,即一個2-node是另一個2-node的左子節點。這種做法的好處是查找的時候不用做任何修改,和普通的二叉查找樹相同。

  紅黑樹是一種具有紅色和黑色鏈接的平衡查找樹,同時滿足:

  • 紅色節點向左傾斜
  • 一個節點不可能有兩個紅色鏈接
  • 整個樹完全黑色平衡,即從根節點到所以葉子結點的路徑上,黑色鏈接的個數都相同。

  下圖可以看到紅黑樹其實是2-3樹的另外一種表現形式:如果我們將紅色的連線水平繪制,那么他鏈接的兩個2-node節點就是2-3樹中的一個3-node節點了。

  紅黑樹的特性:

  • (1)每個節點或者是黑色,或者是紅色。
  • (2)根節點是黑色。
  • (3)每個葉子節點(NIL)是黑色。 [注意:這里葉子節點,是指為空(NIL或NULL)的葉子節點!]
  • (4)如果一個節點是紅色的,則它的子節點必須是黑色的。
  • (5)從一個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點。

下圖是一個典型的紅黑樹,從中可以看到最長的路徑(紅黑相間的路徑)是最短路徑的2倍:平均高度大約為logn

 

紅黑樹這種數據結構應用十分廣泛,在多種編程語言中被用作符號表的實現,如:

  • Java中的java.util.TreeMap,java.util.TreeSet;
  • C++ STL中的:map,multimap,multiset
  • .NET中的:SortedDictionary,SortedSet 等。

(4)B樹和B+樹(B Tree/B+ Tree)

平衡查找樹中的2-3樹以及其實現紅黑樹。2-3樹中,一個節點最多有2個key,而紅黑樹則使用染色的方式來標識這兩個key。B樹,概括來說是一個節點可以擁有多於2個子節點的二叉查找樹。與自平衡二叉查找樹不同,B樹為系統最優化大塊數據的讀和寫操作。B-tree算法減少定位記錄時所經歷的中間過程,從而加快存取速度。普遍運用在數據庫和文件系統

所以B樹其實是對2-3樹的擴展

B+樹是對B樹的變形:

B+ 樹的優點在於:

  • 由於B+樹在內部節點上不好含數據信息,因此在內存頁中能夠存放更多的key。 數據存放的更加緊密,具有更好的空間局部性。因此訪問葉子幾點上關聯的數據也具有更好的緩存命中率。
  • B+樹的葉子結點都是相鏈的,因此對整棵樹的便利只需要一次線性遍歷葉子結點即可。而且由於數據順序排列並且相連,所以便於區間查找和搜索。而B樹則需要進行每一層的遞歸遍歷。相鄰的元素可能在內存中不相鄰,所以緩存命中性沒有B+樹好。

  但是B樹也有優點,其優點在於,由於B樹的每一個節點都包含key和value,因此經常訪問的元素可能離根節點更近,因此訪問也更迅速。

 

B/B+樹常用於文件系統和數據庫系統中,它通過對每個節點存儲個數的擴展,使得對連續的數據能夠進行較快的定位和訪問,能夠有效減少查找時間,提高存儲的空間局部性從而減少IO操作。它廣泛用於文件系統及數據庫中,如:

  • Windows:HPFS文件系統;
  • Mac:HFS,HFS+文件系統;
  • Linux:ResiserFS,XFS,Ext3FS,JFS文件系統;
  • 數據庫:ORACLE,MYSQL,SQLSERVER等中。

樹表查找總結:

  二叉查找樹平均查找性能不錯,為O(logn),但是最壞情況會退化為O(n)。在二叉查找樹的基礎上進行優化,我們可以使用平衡查找樹。平衡查找樹中的2-3查找樹,這種數據結構在插入之后能夠進行自平衡操作,從而保證了樹的高度在一定的范圍內進而能夠保證最壞情況下的時間復雜度。但是2-3查找樹實現起來比較困難,紅黑樹是2-3樹的一種簡單高效的實現,他巧妙地使用顏色標記來替代2-3樹中比較難處理的3-node節點問題。紅黑樹是一種比較高效的平衡查找樹,應用非常廣泛,很多編程語言的內部實現都或多或少的采用了紅黑樹。

  除此之外,2-3查找樹的另一個擴展——B/B+平衡樹,在文件系統和數據庫系統中有着廣泛的應用。

---------------------------------------------------------------------------------------------------------------------------------------------------

6. 分塊查找:分塊查找又稱索引順序查找,它是順序查找的一種改進方法。

7. 哈希查找:散列查找(直接定址),哈希函數構造方法(盡量減少沖突)+解決沖突的方法(開放定址和拉鏈法)

以空間換時間,map的本質就是Hash表

 

------------------------------------------------------------------------------------------

字符串匹配算法:KMP(從O(mn)降低到O(m+n))

KMP如何借助next數組移位 
  道理其實很簡單,如果目標串和模式串的字符匹配,那么就同時移動兩者的下標;如果不能匹配,就使用next數組來獲得移動的數目。但編程方法實現的話,next數組我們需要再修改一下,這樣就能夠直接獲得當前失配位置應當對應的新的模式串字符下標(因為我們關注的是在失配字符之前有幾個匹配的字符)。

所以,next數組來對每個位置找到最長公共前綴

適合主串和子串有很多部分匹配的情況

大致求next數組的代碼:注意這里是設置最開始是-1和0,也可以設置0,1

void kmp(const string& match, const string& pattern) {
    int posP = -1, posM = -1, lenM = match.length(), lenP = pattern.length();
    while (posP < lenP && posM < lenM) {
        if (posP == -1 || pattern[posP] == match[posM]) {
            posP++;
            posM++;
        } else {
            posP = nextArr[posP];
        }
    }
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM