js实现字典树(Trie树)
字典树,又称单词查找树、Trie树,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
现在,我们用js来实现一下这个数据结构。
用一个对象来表示这个树
constructor
class Trie {
constructor() {
this.data = {}
}
}
insert
编写insert方法,通过isEnd属性标记一下,是不是一个完整的单词,方便后续的查询
// 插入一个单词,例如:apple
class Trie {
constructor() {
this.data = {}
}
insert(word) {
let node = this.data
for (let c of word) {
if (node[c]) {
node = node[c]
} else {
node[c] = {}
node = node[c]
}
}
//通过isEnd标记是否是一个完整的单词
node['isEnd'] = true
}
}
let trie=new Trie()
trie.insert('apple')
console.log(JSON.stringify(trie.data));//{"a":{"p":{"p":{"l":{"e":{"isEnd":true}}}}}}
trie.insert('acc')
//{"a":{"p":{"p":{"l":{"e":{"isEnd":true}}}},"c":{"c":{"isEnd":true}}}}
console.log(JSON.stringify(trie.data));
Search
编写search方法,查找trie里是否存在一个完整的单词,通过isEnd属性判断
class Trie {
constructor() {
this.data = {}
}
search(word) {
let node = this.data;
for (let c of word) {
if (!node[c]) {
//trie找不到那个字母也返回false
return false
}
node = node[c]
}
//没有这个属性就返回fasle,有就放回true
return !!node['isEnd'];
}
}
let trie=new Trie()
trie.insert('apple')
console.log(trie.search('app'));// false
console.log(trie.search('apple'));// true
startWith
编写startWith 方法,查找trie中是否存在word的前缀,匹配则返回匹配的节点,方便后续的查找。
class Trie {
constructor() {
this.data = {}
}
startWith(word){
let node =this.data;
for (let c of word){
if(!node[c]){
return false
}
node=node[c]
}
return node
}}
let trie=new Trie()
trie.insert('apple')
console.log(trie.startWith('acc'));//false
console.log(trie.startWith('app'));//{ l: { e: { isEnd: true } } }
console.log(trie.startWith('apple'));//{ isEnd: true }
findSuffix
编写查找后续单词的方法findSuffix,
class Trie {
constructor() {
this.data = {}
}
startWith(word){
let node =this.data;
for (let c of word){
if(!node[c]){
return false
}
node=node[c]
}
return node
}
findSuffix(word){
//递归查找
function findAll(prefix,node,arr=[prefix]) {
for (let key in node){
if(key!=='isEnd'){
let word=prefix+key
arr.push(word)
findAll(word,node[key],arr)
}
}
return arr;
}
let node=this.startWith(word)
if(!node){
return false;
}
return findAll(word,node)
}
}
let trie=new Trie()
trie.insert('apple')
trie.insert('appc')
console.log(trie.findSuffix('app'));//[ 'app', 'appl', 'apple', 'appc' ]
目前只有插入和查询,删除操作比较复杂,待更新