看圖輕鬆理解數據結構與算法系列(Radix樹)

前言

推出一個新系列,《看圖輕鬆理解數據結構和算法》,主要使用圖片來描述常見的數據結構和算法,輕鬆閱讀並理解掌握。本系列包括各類堆、各類隊列、各類列表、各類樹、各類圖、各類排序等等幾十篇的樣子。mysql

Radix樹

Radix樹,即基數樹,也稱壓縮前綴樹,是一種提供key-value存儲查找的數據結構。與Trie不一樣的是,它對Trie樹進行了空間優化,只有一個子節點的中間節點將被壓縮。一樣的,Radix樹的插入、查詢、刪除操做的時間複雜度都爲O(k)。算法

Radix樹特色

  • 通常由根節點、中間節點和葉子節點組成。
  • 每一個節點能夠包含一個或多個字符。
  • 樹的葉子結點數便是數據條目數。
  • 從根節點到某一節點通過路徑的字符連起來即爲該節點對應的字符串。
  • 每一個節點的全部子節點字符串都不相同。

插入操做

對romane、romanus、romulus、rubens、ruber、rubicon、rubicundus七個字符串進行插入,開始插入romane,此時樹爲空,直接建立一個「romane」節點,並將該節點結束標記設爲true,隨即完成romane的插入。sql

image

接着插入romanus,此時根節點已經不爲空,因而從根節點開始逐個字符進行比較,發現二者前綴「roman」相同,須要分割原來的「romane」節點,先建立一個新的公共前綴「roman」節點,網絡

image

而後將原來的「romane」節點設爲「e」,「e」是「romane」除去公共前綴「roman」後剩下的字符,並將新的公共前綴節點指向「e」子節點,子節點索引爲「e」。數據結構

image

接着繼續建立一個新的「us」節點,「us」是「romanus」除去公共前綴「roman」後剩下的字符,併發

image

最後將公共前綴「roman」節點指向「us」子節點,索引爲「u」,並將「us」節點結束標記設爲true。機器學習

image

往下插入romulus,從根節點開始逐個字符進行比較,發現二者前綴「rom」相同,須要分割原來的「roman」節點,先建立一個新的公共前綴「rom」節點,數據結構和算法

image

而後將原來的「roman」節點設爲「an」,「an」是「roman」除去公共前綴「rom」後剩下的字符,並將新的公共前綴節點指向「an」子節點,子節點索引爲「a」。學習

image

接着繼續建立一個新的「ulus」節點,「ulus」是「romulus」除去公共前綴「rom」後剩下的字符,優化

image

最後將公共前綴「rom」節點指向「ulus」子節點,索引爲「u」,並將「ulus」節點結束標記設爲true。

image

繼續插入rubens,從根節點開始逐個字符進行比較,發現二者前綴「r」相同,須要分割原來的「rom」節點,先建立一個新的公共前綴「r」節點,

image

而後將原來的「rom」節點設爲「om」,「om」是「rom」除去公共前綴「r」後剩下的字符,並將新的公共前綴節點指向「om」子節點,子節點索引爲「o」。

image

接着繼續建立一個新的「ubens」節點,「ubens」是「rubens」除去公共前綴「r」後剩下的字符,

image

最後將公共前綴「r」節點指向「ubens」子節點,索引爲「u」,並將「ubens」節點結束標記設爲true。

image

繼續插入ruber,從根節點開始逐個字符進行比較,發現比較完「r」後根節點已經沒有值能夠比較了,因而開始找「r」節點的子節點,

image

根據第二個字符「u」找到對應的子節點,即「ubens」節點,

image

剩餘的「uber」字符串繼續與該節點進行逐一比較,發現二者前綴「ube」相同,須要分割原來的「ubens」節點,先建立一個新的公共前綴「ube」節點,

image

而後將原來的「ubens」節點設爲「ns」,「ns」是「ubens」除去公共前綴「ube」後剩下的字符,並將新的公共前綴節點指向「ns」子節點,索引爲「n」,此外,原來指向「ubens」節點的「u」索引指向「ube」節點。

image

接着繼續建立一個新的「r」節點,「r」是「ruber」除去公共前綴「r」和「ube」後剩下的字符,

image

最後將公共前綴「ube」節點指向「r」子節點,索引爲「r」,並將「r」節點結束標記設爲true。

image

相似地,將rubicon插入樹中,結果以下。

image

繼續插入rubicundus,結果以下。

image

查詢操做

假如查找ruok,從根節點開始比較,「r」相等且根節點已經沒有值能夠繼續比較,

image

因而根據「u」索引找下一個子節點,在「ub」子節點中繼續逐一字符比較,

image

發現無法匹配上「uok」,不存在「ruok」,因而查找結束。

假如查找rubicon,從根節點開始比較,「r」相等且根節點已經沒有值能夠繼續比較,

image

因而根據「u」索引找下一個子節點,在「ub」子節點中繼續逐一字符比較,

image

比較完該節點後繼續根據「i」索引找子節點,在「ic」節點中繼續逐一字符比較,

image

比較完該節點後繼續根據「o」索引找子節點,在「on」節點中繼續逐一字符比較,此時「rubicon」已經完成全部字符的比較,並且「on」節點的結束標記爲true,也就是說存在「rubicon」字符串,查找結束。

image

假如查找roman,從根節點開始比較,「r」相等且根節點已經沒有值能夠繼續比較,

image

因而根據「o」索引找下一個子節點,在「om」子節點中繼續逐一字符比較,

image

比較完該節點後繼續根據「a」索引找子節點,在「an」節點中繼續逐一字符比較,此時「roman」已經完成全部字符的比較,但「an」節點的結束標記爲false,因此「roman」字符串不存在,查找結束。

image

-------------推薦閱讀------------

個人開源項目彙總(機器&深度學習、NLP、網絡IO、AIML、mysql協議、chatbot)

爲何寫《Tomcat內核設計剖析》

個人2017文章彙總——機器學習篇

個人2017文章彙總——Java及中間件

個人2017文章彙總——深度學習篇

個人2017文章彙總——JDK源碼篇

個人2017文章彙總——天然語言處理篇

個人2017文章彙總——Java併發篇


跟我交流,向我提問:

歡迎關注:

相關文章
相關標籤/搜索