Trie 树 ,又叫字典树,前缀树(prefix Tree)、单词查找树 或键树,是一种多叉树结构。如图:
表示关键字集合 {‘a’,‘to’,‘tea’,‘ted’,‘i’,‘in’,‘inn’}。Trie树的基本性质:
- 根节点不包含字符,除根节点外的每一个子节点都包含一个字符
- 从根节点到某一个节点,路径上经过的字符连接起来,为该字节对应的字符串。
- 每一节点的所有子节点包含的字符互不相同。
通常在实现的时候,会在节点结构中设置一个标志,用来标记该节点处是否构成一个单词(关键字)。
208. 实现 Trie (前缀树)
本题为构建一个Trie树,其中3个操作,insert 、search 、startWith。search 是查询输入的单词是不是插入Trie过,startWith是看看有没有相同的前缀,比如apple ,app就是它的一个前缀。
代码如下:
class Trie(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.root={}
def insert(self, word):
"""
Inserts a word into the trie.
:type word: str
:rtype: None
"""
node=self.root
for c in word:
if c not in node:
node[c]={}
node=node[c]
node['is_word']=True #将单词的最后一个字符设置标志位,它的键中‘is_word’对应的值为True
def search(self, word):
"""
Returns if the word is in the trie.
:type word: str
:rtype: bool
"""
node=self.root
for c in word:
if c not in node:
return False
node=node[c]
if 'is_word' in node:
return node['is_word']
else:
return False
def startsWith(self, prefix):
"""
Returns if there is any word in the trie that starts with the given prefix.
:type prefix: str
:rtype: bool
"""
node=self.root
for c in prefix:
if c not in node:
return False
node=node[c]
return True
python 使用嵌套字典来实现树结构,对于非ascii的单词,统一使用unicode编码来插入和与搜索。
字典树常用做高效的文本词语保存,适用于敏感词过滤、关键词提取等场景。在字典树中相同前缀的词之间共享相同的树节点和路径。
#通过字典的嵌套来实现
class Trie():
"""
1.根据一组words进行TrieTree的构建
2.添加某个word
3.查询某个word
4.删除某个word
"""
def __init__(self):
self.trie = {}
self.count = 0
def __repr__(self):
return str(self.trie)
def buildTree(self,wordlist):
for word in wordlist:
t=self.trie
for w in word:
if w not in t:
t[w]={'count':0,'end':False}
t[w]['count']+=1
t=t[w]
self.count+=1
t['end']=True
def add(self,word):
t=self.trie
for w in word:
if w not in t:
t[w]={'count':0,'end':False}
t[w]['count']+=1
t=t[w]
self.count+=1
t['end']=True
def delete(self,word):#仅仅改变end和count属性,字符串仍存在于存储中, 先确定是否存在,若存在沿着的每条路径的count都需要-1
if not self.search(word):
return False
t=self.trie
for w in word:
t=[w]
t['count']-=1
self.count-=1
t['end']=False
def search(self,word):
t=self.trie
for w in word:
if w not in t:
return False
t=t[w]
if t.get('end'):
return True
return False
def prefix_count(self,prefix):
t=self.trie
for w in prefix:
if w not in t:
return -1
t=t[w]
if not t['end']:
return 0
return t['count']
if __name__=="__main__":
Text = ['b','abc','abd','bcd','abcd','efg','hii','bcd']
t=Trie()
t.buildTree(Text)
print(t.prefix_count('bcd'))