基数树

基数树(Radix Tree)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
from collections import defaultdict


class RadixTreeNode():
def __init__(self, is_word=False, keys=None):
self.is_word = is_word
self.children = keys if keys else defaultdict(RadixTreeNode)


class Trie():
def __init__(self):
self.root = RadixTreeNode()

def insert(self, word):
return self.insert_helper(self.root, word)

def insert_helper(self, node, word):
for key, child in node.children.items():
prefix, split, rest = self.match(key, word)
if not split:
# key complete match
if not rest:
# word matched
child.is_word = True
return True
else:
# match rest of word
return self.insert_helper(child, rest)
if prefix:
# key partial match, need to split
new_node = RadixTreeNode(is_word=not rest, keys={split: child})
node.children[prefix] = new_node
del node.children[key]
return self.insert_helper(new_node, rest)
node.children[word] = RadixTreeNode(is_word=True)

def search(self, word):
return self.search_helper(self.root, word)

def search_helper(self, node, word):
for key, child in node.children.items():
prefix, split, rest = self.match(key, word)
if not split and not rest:
return child.is_word
if not split:
return self.search_helper(child, rest)
return False

def startsWith(self, word):
return self.startsWith_helper(self.root, word)

def startsWith_helper(self, node, word):
for key, child in node.children.items():
prefix, split, rest = self.match(key, word)
if not rest:
return True
if not split:
return self.startsWith_helper(child, rest)
return False

def match(self, key, word):
i = 0
for k, w in zip(key, word):
if k != w:
break
i += 1
return key[:i], key[i:], word[i:]

参考资料

python-radix-tree-memory-efficient


基数树
https://wangqian0306.github.io/2021/radix/
作者
WangQian
发布于
2021年11月24日
许可协议