【数据结构与算法】【字符串匹配】Trie树
BF 算法和 RK 算法
BM 算法和 KMP 算法
Trie 樹和 AC 自動機
一、 什么是“Trie樹”?
1. 他是一種樹形結構,是一種專門處理字符串匹配的數據結構,解決在一組字符串集合中快速查找某個字符串的問題。
2. Trie樹的本質是利用字符串之間公共前綴,將重復的前綴合并在一起
Trie 樹的本質,就是利用字符串之間的公共前綴,將重復的前綴合并在一起。
how,hi,her,hello,so,see
其中,根節點不包含任何信息,每個節點表示一個字符串中的字符,從根節點到紅色節點的一條路徑表示一個字符串(紅色節點并不都是葉子節點)。
3. 查找
當在Trie樹中查找一個字符串時,如“her”,就將要查找的字符串分割成單個的字符h,e,r,然后從Trie樹的根節點開始匹配。但,假若要查找的字符串是“he”,用上面同樣的方法,從根節點開始,沿著某條路徑來匹配,發現路徑的最后一個節點“e”不是紅色的,即“he”是某個字符串的前綴,但不能完全匹配任何字符串。
二 、如何實現一課Trie樹?
1,Trie樹主要有兩個操作,一個是將字符串集合構造成Trie樹。這個程可分解為:
- 將一個字符串插入到Trie樹的過程
- 在Trie樹中查詢一個字符串
2,如何存儲一個Trie樹
①:Trie樹是一個多叉樹,需要存儲一個節點的所有子節點的指針。
②:一種經典的存儲方式:借助散列表額思想,通過一個下標與字符一一映射的數組,來存儲子節點的指針。
借助散列表的思想,我們通過一個下標與字符一一映射的數組,來存儲子節點的指針。
假設字符串中只有從a到z這26個小寫字母,從數組中下標為0的位置,存儲指向子節點a的指針,下標為1的位置存儲指向子節點b的指針,以此類推,下標為25的位置,儲存的是指向的子節點z的指針。如果某個字符的子節點不存在,就在對應的下標的位置存儲null。
當在Trie樹中查找字符串的時候,就可以通過字符的ASCII碼減去“a”的ASCII碼,迅速找到匹配的子節點的指針。
3,時間復雜度:
構建 Trie 樹 時間復雜度 O(n)(n 表示所有字符串的長度和)
在 Trie 樹中,查找某個字符串的時間復雜度 O(k),k 表示要查找的字符串的長度
在一組字符串中,頻繁的查詢某些字符串,用Trie樹非常高效。
4,Trie樹很耗內存嗎?
Trie樹是使用數組來儲存一個節點的子節點的指針的,即便一節點只有很少的子節點,遠小于26個,比如2,3個,也要維護一個長度為26的數組。
Trie的本質是避免重復存儲一組字符串的相同前綴子串,但現在每個字符(對應一個節點)的存儲遠遠大于1個字節。
如果字符串中不僅包含小寫字母,還包含大寫字母,數字,甚至是中文,那需要的存儲空間就更多了。所以在重復前綴并不多的情況下,Trie樹不但不節省內存,還有可能浪費更多的內存。
5,Tri樹的優化方案:
-
犧牲一點查詢的效率,將每個節點中的數組換成其他數據結構,來存儲一個節點指針。如:有序數組,跳表,散列表,紅黑樹等。
假設用有序數組,數組中的指針按照指向的子節點中的字符大小順序排序。查詢時,可以通過二分查找的方法,快速查找到某個字符應該匹配的子節點的指針。 -
縮點優化,就是對只有一個子節點的節點,而且此節點不是一個串的結束節點,可以將此子節點合并。這樣可以節省空間,但卻增加了編碼難度。
三 、Trie數與散列表的,紅黑樹的比較(應用與局限 )
1,字符串的匹配問題,籠統上講,其實就是數據的查找問題。
2,在一組字符串中查找字符串,Trie數實際上表現的并不好,他對要處理的字符串有極其嚴苛的要求:
- 第一,字符中包含的字符集不能太大,如果字符集太大,那么存儲空間就可能浪費很多。即便優化也要付出犧牲查詢,插入效率的代價。
- 第二,要求字符串的前綴重合比較到,不然空間消耗會變大很多。
- 第三,如果要用Trie樹解決問題,就需要自己從零開始實現一個Trie樹,還要保證沒有bug,這在工程上是把簡單問題復雜化。
- 第四,通過指針串起來的數據是不連續的,而Trie樹用到了指針,所以,對緩存并不友好。性能上會打個折扣。
綜上:Trie樹不適合精確匹配查找,這種問題更適合用散列表或紅黑樹來解決。Trie樹比較適合的是查找前綴匹配的字符串。Trie的這個特點可以擴展到更加廣泛的一個應用上:自動輸入補全。比如輸入法自動補全功能、IDE 代碼編輯器自動補全功能、瀏覽器網址輸入的自動補全功能等等。
筆記整理來源: 王爭 數據結構與算法之美
總結
以上是生活随笔為你收集整理的【数据结构与算法】【字符串匹配】Trie树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Kali][VMware][2020]
- 下一篇: insertAfter()