Skip to content

Commit 7c0cf25

Browse files
author
YuChengKai
committed
trie
1 parent 4df6d09 commit 7c0cf25

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

DataStruct/dataStruct-zh.md

+81
Original file line numberDiff line numberDiff line change
@@ -555,5 +555,86 @@ _delect(node, v) {
555555
}
556556
```
557557

558+
# Trie
558559

560+
## 原理
561+
562+
在计算机科学,**trie**,又称**前缀树****字典树**,是一种有序树,用于保存关联数组,其中的键通常是字符串。
563+
564+
简单点来说,这个结构的作用大多是为了方便搜索字符串,该树有以下几个特点
565+
566+
- 根节点代表空字符串,每个节点都有 N(假如搜索英文字符,就有 26 条) 条链接,每条链接代表一个字符
567+
- 节点不存储字符,只有路径才存储,这点和其他的树结构不同
568+
- 从根节点开始到任意一个节点,将沿途经过的字符连接起来就是该节点对应的字符串
569+
570+
![](https://user-gold-cdn.xitu.io/2018/6/9/163e1d2f6cec3348?w=640&h=600&f=png&s=48344)
571+
572+
## 实现
573+
574+
总得来说 Trie 的实现相比别的树结构来说简单的很多,实现就以搜索英文字符为例。
575+
576+
```js
577+
class TrieNode {
578+
constructor() {
579+
// 代表每个字符经过节点的次数
580+
this.path = 0
581+
// 代表到该节点的字符串有几个
582+
this.end = 0
583+
// 链接
584+
this.next = new Array(26).fill(null)
585+
}
586+
}
587+
class Trie {
588+
constructor() {
589+
// 根节点,代表空字符
590+
this.root = new TrieNode()
591+
}
592+
// 插入字符串
593+
insert(str) {
594+
if (!str) return
595+
let node = this.root
596+
for (let i = 0; i < str.length; i++) {
597+
// 获得字符先对应的索引
598+
let index = str[i].charCodeAt() - 'a'.charCodeAt()
599+
// 如果索引对应没有值,就创建
600+
if (!node.next[index]) {
601+
node.next[index] = new TrieNode()
602+
}
603+
node.path += 1
604+
node = node.next[index]
605+
}
606+
node.end += 1
607+
}
608+
// 搜索字符串出现的次数
609+
search(str) {
610+
if (!str) return
611+
let node = this.root
612+
for (let i = 0; i < str.length; i++) {
613+
let index = str[i].charCodeAt() - 'a'.charCodeAt()
614+
// 如果索引对应没有值,代表没有需要搜素的字符串
615+
if (!node.next[index]) {
616+
return 0
617+
}
618+
node = node.next[index]
619+
}
620+
return node.end
621+
}
622+
// 删除字符串
623+
delete(str) {
624+
if (!this.search(str)) return
625+
let node = this.root
626+
for (let i = 0; i < str.length; i++) {
627+
let index = str[i].charCodeAt() - 'a'.charCodeAt()
628+
// 如果索引对应的节点的 Path 为 0,代表经过该节点的字符串
629+
// 已经一个,直接删除即可
630+
if (--node.next[index].path == 0) {
631+
node.next[index] = null
632+
return
633+
}
634+
node = node.next[index]
635+
}
636+
node.end -= 1
637+
}
638+
}
639+
```
559640

0 commit comments

Comments
 (0)