字典树(Trie)-Swift实现

博客从谷歌搜索引出字典树,介绍其为前缀树、递归数据结构,虽未广泛应用但有实用价值,插入和搜索操作时间复杂度为O(n)。还提及在Swift里可让每个字典树包含字典关联子字典树,以及存储序列所需函数等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果你谷歌“cool data structures”,你搜索到的第一个结果就会是这个内容。这是一个stackoverflow问题:“有哪些数据结构比较少人知道,但是很有用?”,点赞最多的第一条答案就是字典树。我仔细研究了这些关于字典树答案,在其应用方面发现了一些有趣的事情(也发现我自己也是这种谷歌“cool data structures”的那种人),所以,我来到xcode playground,写下这些代码。

字典树就是前缀树,是一种递归数据结构:每个字典树都包含其他的子树,可以通过前缀来识别。

这是一种比较时髦的数据结构,并没有被广泛的应用,但是确有一些非常实用的应用。它有类似集合的操作,包括插入和搜索操作时间复杂度在O(n),其中n是搜索序列的长度。集合是可hash的无序元素的唯一方式,但是,针对有序的hash元素序列,字典树或许更适合你。(有一件事需要告诉你,就是集合能够针对元素自身hash,所以,如果你想存储的序列是无序的,一个元素是集合的集合是更适合的。)

A trie for keys “A”, “to”, “tea”, “ted”, “ten”, “i”, “in”, and “inn”.

在Swift里面,我们能够使每一个字典树包含一个字典,字典包含前缀和字典树。类似这样:

public struct Trie<Element : Hashable> {
    private var children: [Element:Trie<Element>]
}
复制代码

我们不会遇到结构体不能递归的情况,因为我们不直接存储一个字典树在一个字典树里面——我们存储的是一个字典,并且会关联到子字典树,在这个字典里面,前缀是这个字典的键值。所以,怎么补充接下来的内容呢(初始化)?我们可以像列表生成器一样分解属性:

extension Trie {
    private init<G : GeneratorType where G.Element == Element>(var gen: G) {
        if let head = gen.next() {
            children = [head: Trie(gen: gen)]
        } else {
            children = [:]
        }
    }
    public init<S : SequenceType where S.Generator.Element == Element>(_ seq: S) {
        self.init(gen: seq.generator())
    }
}
复制代码

这还不够,想要存储一个序列,我们还要一个insert函数,方法如下:

extension Trie {
    private mutating func insert<G : GeneratorType where G.Element = Element>(var gen: G) {
        if let head = gen.next() {
            children[head]?.insert(gen) ?? {children[head] == Trie(gen: gen)}()
        }
    }
    public mutating func insert<S : SequenceType where S.Generator.Element == Element>(_ seq: S) {
        insert(seq.generate())
    }
}
复制代码

转载于:https://juejin.im/post/5ce525175188252db55ce39c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值