一.前缀树描述
前缀树(Trie树),类似于一种多叉树的数据结构,每一个节点存储字符串的一个字符,多个节点组合起来形成一个完整的字符串。前缀树有三个特点:
- 根节点不包含字符串,除了根节点,其他节点都只包含一个字符;
- 每个节点的所有子节点包含的字符都不相同;
- 从根节点到某个子节点,节点的字符连接起来形成一个字符串;
- 每个节点的子节点拥有相同的前缀。
二.前缀树结构
2.1 前缀树的结构如下
图 2.1
- 如上图,是一个简单的前缀树结构,其包含了六个字符串:
- 如需查找“中国人”,只需要依次判断当前节点是否包含每个字符即可,不需要遍历每个字符串是否与查找的字符串相等。
2.2 前缀树的实现
- 前缀树可以实现最基本增加,删除和搜索功能,但一般只会用到增加和搜索;
- 如图 2.1,每个节点可能有0个或1个或多个子节点和一个字符(除跟节点),则可以使用Map存储节点信息,key为当前节点的字符,value是当前节点的子节点,如下:
public int endCount; public Map<Character, TrieNode> children; public TrieNode() { endCount = 0; children = new ConcurrentHashMap<>(); }
代码中的 endCount 表示以当前节点为结尾的字符串的个数,示例代码参考:前缀树
-
除了Map,也可以使用数组来实现,数组表示当前节点的子节点,如果是字符串查找,数组大小为26,刚好满足所有的需求。
三.前缀树的效率
3.1 复杂度
- 时间复杂度
由于trie树结构中使用的HashMap,而Map的时间复杂度可能是 O(1)、O(logn)、O(n),则trie的时间复杂度同map。
- 空间复杂度
由于查找过程中没有使用额外的空间,故,空间复杂度为O(1)。
四.前缀树应用场景
- 字符串的快速检索
- 最长公共前缀
- 字符串排序