本文是對 Swift Algorithm Club 翻譯的一篇文章。 Swift Algorithm Club是 raywenderlich.com網站出品的用Swift實現算法和數據結構的開源項目,目前在GitHub上有18000+⭐️,我初略統計了一下,大概有一百左右個的算法和數據結構,基本上常見的都包含了,是iOSer學習算法和數據結構不錯的資源。 🐙andyRon/swift-algorithm-club-cn是我對Swift Algorithm Club,邊學習邊翻譯的項目。因爲能力有限,如發現錯誤或翻譯不妥,請指正,歡迎pull request。也歡迎有興趣、有時間的小夥伴一塊兒參與翻譯和學習🤓。固然也歡迎加⭐️,🤩🤩🤩🤨🤪。 本文的翻譯原文和代碼能夠查看🐙swift-algorithm-club-cn/Triegit
字典樹(Trie)github
這個話題已經有個輔導文章算法
Trie
(在一些其餘實現中也稱爲前綴樹或基數樹)是用於存儲關聯數據結構的特殊類型的樹。 Trie
做爲一個字典可能以下所示:swift
存儲英語是Trie
的主要用處。 Trie
中的每一個節點都表明一個單詞的單個字符。 而後,一系列節點組成一個單詞。數據結構
字典樹對某些狀況很是有用。 如下是一些優勢:學習
Trie
不須要擔憂鍵衝突。Trie
結構默認按字母順序排列。Trie
結構很是適合查找操做。 對於模擬英語語言的Trie
結構,找到一個特定的單詞就是幾個指針遍歷的問題:網站
func contains(word: String) -> Bool {
guard !word.isEmpty else { return false }
// 1
var currentNode = root
// 2
var characters = Array(word.lowercased().characters)
var currentIndex = 0
// 3
while currentIndex < characters.count,
let child = currentNode.children[characters[currentIndex]] {
currentNode = child
currentIndex += 1
}
// 4
if currentIndex == characters.count && currentNode.isTerminating {
return true
} else {
return false
}
}
複製代碼
contains
方法至關簡單:ui
root
的引用。 此引用將容許您沿着節點鏈向下走。isTerminating
是一個布爾標誌,表示該節點是不是單詞的結尾。 若是知足此if
條件,則意味着您能夠在trie
中找到該單詞。插入Trie
須要您遍歷節點,直到您中止必須標記爲terminating
的節點,或者到達須要添加額外節點的點。spa
func insert(word: String) {
guard !word.isEmpty else {
return
}
// 1
var currentNode = root
// 2
for character in word.lowercased().characters {
// 3
if let childNode = currentNode.children[character] {
currentNode = childNode
} else {
currentNode.add(value: character)
currentNode = currentNode.children[character]!
}
}
// Word already present?
guard !currentNode.isTerminating else {
return
}
// 4
wordCount += 1
currentNode.isTerminating = true
}
複製代碼
Trie
裏面兩個共享字母的詞(即「Apple」,「App」)。若是一個字母已經存在,你將重複使用它,並簡單地遍歷鏈條。 不然,您將建立一個表示該字母的新節點。isTerminating
標記爲true,將該特定節點標記爲單詞的結尾。從字典樹中刪除鍵有點棘手,由於還有一些狀況須要考慮。 Trie
中的節點能夠在不一樣的單詞之間共享。 考慮兩個詞「Apple」和「App」。 在Trie
中,表明「App」的節點鏈與「Apple」共享。翻譯
若是你想刪除「Apple」,你須要注意保持「App」鏈。
func remove(word: String) {
guard !word.isEmpty else {
return
}
// 1
guard let terminalNode = findTerminalNodeOf(word: word) else {
return
}
// 2
if terminalNode.isLeaf {
deleteNodesForWordEndingWith(terminalNode: terminalNode)
} else {
terminalNode.isTerminating = false
}
wordCount -= 1
}
複製代碼
findTerminalNodeOf
遍歷字典樹,找到表明word
的最後一個節點。 若是它沒法遍歷字符串,則返回nil
。deleteNodesForWordEndingWith
遍歷後綴,刪除word
表示的節點。設n是Trie
中某個值的長度。
contains
- 最差狀況O(n)insert
- O(n)remove
- O(n)count
:返回Trie
中的鍵數 —— O(1)words
:返回包含Trie
中全部鍵的列表 —— O(1)isEmpty
:若是Trie
爲空則返回true
,不然返回false
—— O(1)擴展閱讀字典樹的維基百科
做者:Christian Encarnacion, Kelvin Lau
翻譯:Andy Ron 校對:Andy Ron