1. Trie树是什么?
Trie(发音为“try”或“tree”)是一种树形数据结构,专门用于高效处理字符串(或其他序列)集合。它的全称是“retrieval tree”(检索树),核心思想是将字符串的字符逐个分解存储在树的节点中,共享相同前缀的字符串会复用相同的路径。
1.1 Trie树的核心特点
- 前缀共享:相同前缀的字符串共享相同的路径,从而节省存储空间。
- 高效查询:查找、插入等操作的时间复杂度通常只与字符串长度相关,与集合大小无关。
- 多用途:支持前缀查询、模糊匹配、自动补全等功能。
- 有序性:可以按字典序遍历所有字符串。
1.2 Trie树的典型应用场景
- 搜索引擎的自动补全(如Google搜索框)。
- 拼写检查器(如Word的拼写建议)。
- IP路由表查找。
- 字典实现(如电话簿)。
- 字符串匹配算法(如KMP或AC自动机的预处理)。
2. Trie树的结构
Trie树是一棵多叉树,每个节点可能有多个子节点,对应于可能的字符(通常是字母、数字等)。以下是Trie树的结构细节:
2.1 节点结构
一个典型的Trie节点包含以下内容:
- 子节点指针:指向所有可能字符的子节点。通常用数组、哈希表或链表实现。
- 标记:表示该节点是否为一个完整字符串的结束点(通常用布尔值
isEnd
或计数器count
)。 - 可选信息:如频率、前缀计数等(视应用而定)。
例如,对于字母表大小为26(仅小写字母)的Trie,节点可能定义为:
class TrieNode:
def __init__(self):
self.children = [None] * 26 # 存储26个字母的子节点
self.isEnd = False # 标记是否为单词结尾
2.2 Trie树的根节点
- Trie树有一个空根节点,不存储任何字符,仅作为树的起点。
- 从根节点开始,每条路径表示一个字符串的前缀。
2.3 示例
假设插入单词cat
、car
、cap
,Trie树的结构如下:
(root)
/ | \
c a b
/ | |
a r e
/ \ |
t p t
- 路径
c->a->t
表示cat
。 - 路径
c->a->r
表示car
。 - 路径
c->a->p
表示cap
。 - 节点
t
、r
、p
的isEnd
为True
,表示它们是单词的结尾。
3. Trie树的基本操作
Trie树支持以下核心操作:插入、查找、删除和前缀查询。下面逐一讲解,并提供伪代码和Python实现。
3.1 插入(Insert)
插入一个字符串到Trie树的过程是将字符串的每个字符逐个添加到树中,并确保共享前缀。
步骤:
- 从根节点开始,遍历字符串的每个字符。
- 对于每个字符:
- 如果当前节点的对应子节点不存在,创建新节点。
- 移动到该子节点。
- 在字符串最后一个字符的节点标记
isEnd = True
.
伪代码:
function insert(root, word):
node = root
for char in word:
if node.children[char] is null:
node.children[char] = new TrieNode()
node = node.children[char]
node.isEnd = true
时间复杂度:
- O(m)O(m)O(m), 其中mmm是字符串长度。
示例代码:
class TrieNode:
def __init__(self):
self.children = {
}
self.isEnd = False
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word):
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.isEnd = True
3.2 查找(Search)
查找一个字符串是否存在于Trie树中。
步骤:
- 从根节点开始,遍历字符串的每个字符。
- 对于每个字符:
- 如果对应子节点不存在,返回
False
。 - 移动到该子节点。
- 如果对应子节点不存在,返回
- 检查最后一个节点的
isEnd
是否为True
.
伪代码:
function search(root, word):
node = root
for char in word:
if node.children[char] is null:
return false
node = node.children[char]
return node.isEnd