在實現字典樹(前綴樹)之前,我們先看一下什么是字典樹(前綴樹)
“字典樹又稱前綴樹,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 }
歡迎評論!!共同進步!!
(請問博客園中插入代碼時“行內代碼”選項是什么意思??)