下面用2種分別用map和數組實現字典樹:
(方法1)map實現,用map實現的方法意義不大,還不如直接用map,主要是實現方法里面
分為非遞歸和遞歸兩種算法
type trieNode struct {
isWord bool // 是否是單詞結尾
next map[rune]*trieNode
}
type trie struct {
size int // 節點數量
root *trieNode
}
func NewTrie() *trie {
return &trie{
0,
&trieNode{false, make(map[rune]*trieNode)},
}
}
func (this *trie) GetSize() int {
return this.size
}
// 非遞歸算法
func (this *trie) Add(word string) {
if len(word) == 0 {
return
}
cur := this.root
for _, v := range word {
_, ok := cur.next[v] // 在NewTrie中已經初始化,能直接用
if !ok {
cur.next[v] = &trieNode{false, map[rune]*trieNode{}}
}
cur = cur.next[v]
}
// 判斷該單詞之前是否已經添加到tree中了
if !cur.isWord {
cur.isWord = true
this.size++
}
}
// 遞歸算法
func (this *trie) Add2(word string) {
if len(word) == 0 {
return
}
cur := this.root
this.size = this.size + cur.insert(word)
}
// 輔助完成遞歸函數:在node節點中插入word,如果是已經存在的單詞,返回0,如果不存在返回1
func (node *trieNode) insert(word string) int {
_, ok := node.next[rune(word[0])]
if !ok {
node.next[rune(word[0])] = &trieNode{false,
map[rune]*trieNode{}}
}
node = node.next[rune(word[0])]
if len(word) == 1 {
if !node.isWord {
node.isWord = true
return 1
}
return 0
}
return node.insert(word[1:])
}
// 查詢是否包含某個單詞
func (this *trie) Contains(word string) bool {
if len(word) == 0 {
return false
}
cur := this.root
for _, v := range word {
t1, ok := cur.next[v]
if !ok {
return false
}
cur = t1
}
return cur.isWord
}
// 前綴是否有以prefix為前綴的單詞
func (this *trie) IsPrefix(word string) bool {
if len(word) == 0 {
return false
}
cur := this.root
for _, v := range word {
t1, ok := cur.next[v]
if !ok {
return false
}
cur = t1
}
return true
}
(方法2)用數組實現字典樹
type trie struct {
size int
isWord bool
// 只支持26個小寫字母或大寫字母,根據實際情做改變況而定
next [26]*trie
}
func NewTrie() *trie {
return new(trie)
}
func (this *trie) Insert(word string) {
if len(word) == 0 {
return
}
cur := this
for i, _ := range word {
if cur.next[word[i]-'a'] == nil {
cur.next[word[i]-'a'] = new(trie)
}
cur = cur.next[word[i]-'a']
}
if !cur.isWord {
cur.isWord = true
cur.size++
}
}
// 是否包含某個單詞
func (this *trie) Contains(word string) bool {
length := len(word)
if length == 0 {
return false
}
cur := this
for i := 0; i < length; i++ {
if cur = cur.next[i]; cur == nil {
return false
}
}
return cur.isWord
}
// 是否包含preWith前綴的單詞
func (this *trie) IsPrefix(preWith string) bool {
length := len(preWith)
if length == 0 {
return true
}
cur := this
for i := 0; i < length; i++ {
if cur := cur.next[i]; cur == nil {
return false
}
}
return true
}
相關:
1)trie解決leetcode-207:實現trie
http://www.lxweimin.com/p/d95153f382f6
2)trie解決leetcode-211:添加與搜索單詞
http://www.lxweimin.com/p/74103f51aa36
3)trie解決leetcode-677:鍵值映射
http://www.lxweimin.com/p/dd247d5591a2
有bug歡迎指出,轉載請注明出處。