【玩转数据结构Part5】线段树/Trie(字典树)

线段树

线段树不是完全二叉树,
线段树是平衡二叉树

Trie(字典树 / 前缀树)

https://blog.csdn.net/johnny901114/article/details/80711441

Trie是多叉树。
Trie和字典的区别:如果有n个条目,使用字典查询(底层是二叉树),查询的时间复杂度为O(logn),而Trie
查询每个条目的复杂度,与字典中一共有多少条目无关,只与要查询的字符串长度w有关,时间复杂度为O(w)。
用Trie实现字符串查找,性能比集合好。

节点的定义:

class TrieNode: # Trie字典树的最基本单元Node的定义
    def __init__(self):
        self.isword = False # 表示从根节点到该节点组成的字符串是否为一个word
        self.next = {}  # 是一个映射(字典)(因为Trie是多叉树,每个节点有多个后继节点)

添加字符串

def add(self, word): # 往Trie中添加一个字符串,要把字符串拆成字符,将字符做成节点,加入Trie
    cur_node = self.root
    for ch in word: # 遍历字符串中的每个字符
        if not cur_node.next.get(ch):
            cur_node.next[ch] = TrieNode()
        cur_node = cur_node.next[ch]

    if not cur_node.isword:  # 当遍历完字符串时,先判断该字符串是否已经在Trie中了,确保不会添加重复的单词
        cur_node.isword = True
        self.size += 1

查询字符串

查询Trie中是否包含某一个单词

def contains(self,word): # 查询Trie中是否包含某一个单词
    cur_node = self.root
    for ch in word:
        if not cur_node.next.get(ch):
            return False
        cur_node = cur_node.next[ch]
    return cur_node.isword

查询前缀

在Trie中查找,是否有单词以prefix为前缀

def isPrefix(self, prefix): # 在Trie中查找,是否有单词以prefix为前缀
    cur_node = self.root
    for ch in prefix:
        if not cur_node.next.get(ch):
            return False
        cur_node = cur_node.next[ch]
    return True

总结

Trie的局限性

Trie最大的问题:空间。

解决方法:

  • 压缩字典树,压缩字典树就是将多个单节点压缩在一起,一定程度上节省了空间,但是维护的成本更高
  • Ternary Search Trie(三分搜索字典树)

扩展:后缀树。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值