字典樹(前綴樹)的實現


在實現字典樹(前綴樹)之前,我們先看一下什么是字典樹(前綴樹)

“字典樹又稱前綴樹,Trie樹,是一種樹形結構,是一種哈希樹的變種。典型應用是用於統計,排序和保存大量的字符串(但不僅限於字符串),所以經常被搜索引擎系統用於文本詞頻統計。

它的優點是:利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較,查詢效率比哈希樹高。”------百度百科

 

字典樹是一種樹形結構,優點是利用字符串的公共前綴來節約存儲空間。

 字典樹如圖1所示:

                                             圖1

在字典樹上搜索添加過的單詞的步驟如下:

1、從根結點開始搜索

2、取得要查找單詞的第一個字母,並根據該字母選擇對應的字符路徑向下繼續搜索。

3、字符路徑指向的第二層節點上,根據第二個字母選擇對應的字符路徑向下繼續搜索。

4、一直向下搜索,如果單詞搜索完后,找到的最后一個節點是一個終止節點,比如圖1中的實心節點,說明字典樹中含有這個單詞,

如果找到的最后一個節點不是一個終止節點,說明單詞不是字典樹中添加過的單詞。如果單詞沒搜索完,但是已經沒有后續的節點了,

也說明單詞不是字典樹中添加過的單詞。

 

題目:字典樹(前綴樹)的實現:

字典樹又稱為前綴樹或Trie樹,是處理字符串常見的數據結構。假設組成所有單詞的字符串是“a”~“z”,請實現字典樹結構,並包含以下四個主要功能。

void insert(String word): 添加word,可以重復添加。

void delete(String word):刪除word,如果word添加過多次,僅刪除一個。

boolean search(String word):查詢word是否在字典樹中。

int prefixNumber(String pre):返回以字符串pre為前綴的單詞數量。

 

 1 class TrieNode {
 2     int path;
 3     int end;
 4     TrieNode[] map;
 5 
 6     TrieNode() {
 7         path=0;
 8         end=0;
 9         map=new TrieNode[26];
10     }
11 }
12 class Trie {
13     private TrieNode root;
14     public Trie() {
15         root=new TrieNode();
16     }
17     public void insert(String word) {
18         if (word==null) {
19             return;
20         }
21         char[] chs=word.toCharArray();
22         TrieNode node=root;
23         node.path++;
24         int index=0;
25         for (int i=0; i<chs.length; i++) {
26             index=chs[i]-'a';
27             if (node.map[index]==null) {
28                 node.map[index]=new TrieNode();
29             }
30             node=node.map[index];
31             node.path++;
32         }
33         node.end++;
34     }
35     public void delete(String word) {
36         if (search(word)) {
37             char[] chs=word.toCharArray();
38             TrieNode node=root;
39             node.path--;
40             int index=0;
41             for (int i=0; i<chs.length; i++) {
42                 index=chs[i]-'a';
43                 node.map[index].path--;
44                 node=node.map[index];
45             }
46             node.end--;
47         }
48     }
49     public boolean search(String word) {
50         if (word==null) {
51             return false;
52         }
53         char[] chs=word.toCharArray();
54         TrieNode node=root;
55         int index=0;
56         for (int i=0; i<chs.length; i++) {
57             index=chs[i]-'a';
58             if (node.map[index]==null) {
59                 return false;
60             }
61             node=node.map[index];
62         }
63         return node.end!=0;
64     }
65     public int prefixNumber(String pre) {
66         if (pre==null) {
67             return 0;
68         }
69         char[] chs=pre.toCharArray();
70         TrieNode node=root;
71         int index=0;
72         for (int i=0; i<chs.length; i++) {
73             index=chs[i]-'a';
74             if (node.map[index]==null) {
75                 return 0;
76             }
77             node=node.map[index];
78         }
79         return node.path;
80     }
81 }

 

 LeetCode208實現Trie(前綴樹)

題目描述:

實現一個 Trie (前綴樹),包含 insert, search, 和 startsWith 這三個操作。

示例:

Trie trie = new Trie();

trie.insert("apple");
trie.search("apple"); // 返回 true
trie.search("app"); // 返回 false
trie.startsWith("app"); // 返回 true
trie.insert("app");
trie.search("app"); // 返回 true
說明:

你可以假設所有的輸入都是由小寫字母 a-z 構成的。
保證所有輸入均為非空字符串。

 

 1 class TrieNode {
 2     int path;
 3     int end;
 4     TrieNode[] map;
 5 
 6     TrieNode() {
 7         path=0;
 8         end=0;
 9         map=new TrieNode[26];
10     }
11 }
12 class Trie {
13     private TrieNode root;
14     public Trie() {
15         root=new TrieNode();
16     }
17     public void insert(String word) {
18         if (word==null) {
19             return;
20         }
21         char[] chs=word.toCharArray();
22         TrieNode node=root;
23         node.path++;
24         int index=0;
25         for (int i=0; i<chs.length; i++) {
26             index=chs[i]-'a';
27             if (node.map[index]==null) {
28                 node.map[index]=new TrieNode();
29             }
30             node=node.map[index];
31             node.path++;
32         }
33         node.end++;
34     }
35     public boolean search(String word) {
36         if (word==null) {
37             return false;
38         }
39         char[] chs=word.toCharArray();
40         TrieNode node=root;
41         int index=0;
42         for (int i=0; i<chs.length; i++) {
43             index=chs[i]-'a';
44             if (node.map[index]==null) {
45                 return false;
46             }
47             node=node.map[index];
48         }
49         return node.end!=0;
50     }
51     public boolean startsWith(String prefix) {
52         if (prefix==null) {
53             return false;
54         }
55         char[] chs=prefix.toCharArray();
56         TrieNode node=root;
57         int index=0;
58         for (int i=0; i<chs.length; i++) {
59             index=chs[i]-'a';
60             if (node.map[index]==null) {
61                 return false;
62             }
63             node=node.map[index];
64         }
65         return node.path!=0;
66     }
67 }

歡迎評論!!共同進步!!

(請問博客園中插入代碼時“行內代碼”選項是什么意思??)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM