相比之前我们介绍的红黑树和B树,Trie树是一种什么样的树形结构?
Trie树,也叫字典树,又称单词查找树,是一种树形结构, 是一种哈希树的变种。典型应用是用于统计, 排序和保存大量的字符串(但不仅限于字符串), 所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间, 最大限度地减少无谓的字符串比较,查询效率比哈希树高
它有3个基本性质:
如下图:
由于使用Java不方便直观的看效果,这里使用JS实现,我们看下效果:
要实现这种功能,我们首先需要构建Trie树,然后通过深度优先算法得到完整的字符串。
首先定义结点
class Node {
constructor(value) {
this.val = value;//数值
this.child = [];//孩子结点
this.end = false;//是否是独立的单词
this.height = 0;//深度
this.num = 1;//经过单词数量
}
search(key) {
for (let i = 0; i < this.child.length; ++i) {
if (this.child[i].val == key) {
return this.child[i];
}
}
return null;
}
}
构造完结点,就是构建Trie树了
class TrieTree {
constructor() {
this.root = new Node(null);
this.size = 1;
}
insert(value) {
let node = this.root;
for (let ch of value) {
let son = node.search(ch);
if (son == null) {
son = new Node(ch);//构建
son.height = node.height + 1;
node.child.push(son);
} else {
son.num++;
}
node = son;//向下递归
}
if (!node.end) {//不是结束标志,则增加结束标志
this.size++;
node.end = true;
}
}
}
构建完之后就是自动补全了,核心是深度优先的递归算法
//自动补全
relate(value) {
let node = this.root;
let arr = [];
let word = "";
$("#relate").html("");
for (let ch of value) {
let son = node.search(ch);
if (son == null) {
//不存在前缀
return arr;
}
node = son;
}
//存在公共前缀,将该分支下数据输出
console.log("存在" + value + "公共前缀")
//深搜
this.DFS(arr, value, node);
console.log(arr)
for (let w of arr) {
$("#relate").append("<p>" + w + "</p>")
}
}
DFS(arr, value, node) {
if (node != null) {
for (var i = 0; i < node.child.length; ++i) {
if (node.child[i].end) {
arr.push(value + node.child[i].val)
}
this.DFS(arr, value + node.child[i].val, node.child[i])
}
}
}