Trie也可以叫做Prefix Tree(前缀树),也是一种搜索树。Trie分步骤存储数据,树中的每个节点代表一个步骤,trie常用于存储单词以便快速查找,比如实现单词的自动完成功能。 Trie中的每个节点都包含一个单词的字母,跟着树的分支可以可以拼写出一个完整的单词,每个节点还包含一个布尔值表示该节点是否是单词的最后一个字母。
function Node() {
this.keys = new Map();
this.end = false;
this.setEnd = function () {
this.end = true;
}
this.isEnd = function () {
return this.end;
}
}
function Trie() {
this.root = new Node();
/*
向字典树中增加一个单词
*/
this.add = function (input, node = this.root) {
if(input != null){
//空字符串的时候,就默认结束
if(input.length === 0){
node.setEnd();
return;
}else if(!node.keys.has(input[0])){//没有加入节点
node.keys.set(input[0], new Node());
//继续加下一个字符
return this.add(input.substr(1), node.keys.get(input[0]));
}else{
//加入了节点
return this.add(input.substr(1), node.keys.get(input[0]));
}
}
}
/*
判断字典树中是否包含某个单词
*/
this.isWord = function (word) {
var node = this.root;
if(word){
while(word.length > 1){
//是否有第一个字符,没有的话,就不是单词
if(!node.keys.has(word[0])){
return false;
}else{
//循环遍历往下面找
node = node.keys.get(word[0]);
word = word.substr(1);
}
}
//最后如果找到结尾了,就是单词,否则就不是
return (node.keys.has(word) && node.keys.get(word).isEnd()) ? true: false;
}
}
/*
返回字典树中的所有单词
*/
this.print = function () {
var words = [];
var search = function (node = this.root, string) {
if(node.keys.size != 0){
//循环遍历找到keys每一个字符,拼接起来
for(var letter of node.keys.keys()){
search(node.keys.get(letter), string.concat(letter))
}
//找到结尾是单词的话,就保存在数组中
if(node.isEnd()){
words.push(string);
}
}else{
string.length > 0 ? words.push(string) : undefined;
}
}
//根节点开始找
search(this.root, "");
return words.length > 0 ? words : null;
}
}