本文是对 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