Python实现字典树-Trie

博客介绍了字典树(Trie),它是一种树型数据结构,用于存储大量字符串,时间复杂度与查询字符串长度有关。还阐述了节点设计,无需存节点代表的字符串,用字典存孩子节点信息。给出了数据结构设计的函数定义,如添加单词、查询是否包含单词等。

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

本篇文章将解释什么是字典树以及字典树的Python实现

什么是字典树(Trie)

字典树是一种树型数据结构,通常用来存储大量字符串。字典树的每个节点通常都为一个字符。从根节点的第一个孩子节点开始到可以作为字符串结尾的节点的路径就是Trie所存储的字符串,这种存储方式带来的好处就是Trie的时间复杂度和存储字符串的数据量无关只与查询的字符串长度有关,这也是字典树存在的主要意义之一。
下面以存储单词为例实现一颗字典树,实际上Python中字典是动态数据结构理论上是不会限制字典树支持的字符种类,但在一些静态语言中可能需要额外注意开辟多大的字典空间

节点设计

  1. Trie的节点无需存储节点代表的字符串,只需要存储节点是否是某一字符串的结尾;
  2. Trie要存储孩子节点的信息,这里采用字典进行存储,也就是说'在访问到孩子节点的时候就可以确定孩子节点所代表的字符',所以字典树不用存储字符本身;
class Node(object):
    def __init__(self, is_word = False):
    	# True 表示这个节点是一个字符串的结尾
        self.is_word = is_word
        # node key 中存储着孩子节点代表的字符 value 中存储着孩子节点的指针
        self.node = {}

数据结构设计

  1. def add(word) // return None 向Trie中添加一个单词
  2. def contains(word) // return bool 询问Trie是否包含word
  3. def is_prefix(prefix) // return bool 询问字典树是否包含该前缀的单词
  4. def size() // ruturn int 返回字典树存储单词个数

实现

class Node(object):
    def __init__(self, is_word = False):
        self.is_word = is_word
        self.node = {}

# 为了保证数据结构的Python风格,有些功能采用魔法函数实现
class Trie(object):

    def __init__(self):

        self.size = 0
        self.root = Node()
        
    def __len__(self):
        return self.size

    def add(self, word):

        cur = self.root

        for char in word:
            if cur.node.get(char) is None:
                cur.node[char] = Node()

            cur = cur.node[char]

        if not cur.is_word:
            cur.is_word = True
            self.size += 1

    def add_by_recursion(self, word):
        self.__add(word, 0, self.root)

    def __add(self, word, i, cur):

        if i == len(word):
            if not cur.is_word:
                cur.is_word = True
                self.size += 1
            return

        if cur.node.get(word[i]) is None:
            cur.node[word[i]] = Node()

        self.__add(word, i + 1, cur.node[word[i]])

    def __contains__(self, item):

        cur = self.root

        for char in item:
            if cur.node.get(char) is None:
                return False

            cur = cur.node[char]

        return cur.is_word

    # 前缀搜索
    def is_prefix(self, prefix):
        cur = self.root

        for char in prefix:
            if cur.node.get(char) is None:
                return False
            cur = cur.node[char]

        return True

转载注明出处

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值