字典樹的建立、刪除、查詢
阿新 • • 發佈:2019-02-17
package arithmetic; import java.util.*; class DicNode { int count;//當前字元在這個位置出現的次數 int next[] = new int[26];//其下一個字元的指標 ,next[i] 中, i 表示字元 ch , next[i] 表示地址 public String toString() { StringBuffer s = new StringBuffer(); s.append(count+" |"); for(int i =0;i<26;i++) { if(next[i]==0) s.append(" | "); else s.append((char)(i+'a')+"| "); } return s.toString(); } } public class DicTree { static DicNode tree[] = new DicNode[10000]; public static void main(String args[]) { for(int i =0;i<tree.length;i++) tree[i]= new DicNode(); create("abcdefg"); create("ab"); create("google"); for(int i =0;i<7;i++) { System.out.print(i+" "); System.out.println(tree[i].toString()); } System.out.println(find("google")); del("google"); System.out.println(find("google")); } public static void create(String str) { int treepos =1; int index = 0; for(int i = 0;i<str.length();i++) { int ch = str.charAt(i)-'a'; if(tree[tree[index].next[ch]].count==0) //表明 字元 ch 還不在樹中 { tree[index].next[ch]=treepos;// tree[index].next[ch] 表示指向 ch 結點的孩子指標,裡面存放的是 ch 在樹中的位置,其值為索引 tree[treepos++].count=1; }else { tree[tree[index].next[ch]].count++; } index = tree[index].next[ch]; //當前結點變為其孩子結點 } } public static int find(String str)//找出有沒有以str 為引數的單詞,如果有,在檔案中出現幾次,沒有返回0 { int index = 0; for(int i =0;i<str.length();i++) { int ch = str.charAt(i)-'a'; if(tree[tree[index].next[ch]].count!=0) //表示出現過 index = tree[index].next[ch]; else return 0; } return tree[index].count; } public static void del(String str) { int index =0 ; if(find(str)==0) { System.out.println("this word not find..."); return ; } for(int i=0;i<str.length();i++) { int ch = str.charAt(i)-'a'; tree[tree[index].next[ch]].count--; index=tree[index].next[ch]; } } } /* * 字典樹建立 * 1.定義一個字典樹的結點,最簡單的是裡面有兩個變數,count 表示出現次數,next[i] i 可以直接表示字元,next[i]裡面儲存是地址,是孩子結點的地址,其實就是孩子結點在tree[] 數組裡面的索引變數 * 2.迴圈單詞的所有字元,建立樹進,對於一個單詞,只可能向下走,不能向回走 * 3.treepos 表示已經插入的結點的個數,index 表示在插入一個單詞的字元時,走到當前結點在tree[] 裡面的位置,也就是當前結點的位置 * 4.tree[index].next[ch] 表示當前結點的孩子結點中,儲存字元 ch 的孩子結點的索引,靠,有點不好表達,要插入字元 b, * tree[index].next[b-'a'] 表示的就是 當前所有結點中 字元為b 的結點, 那麼 tree[index].next[b-'a'] 裡面存放的值就是其孩子結點在tree[] 中的索引 * 5.如果其孩子結點中的count 值為0,那麼就表示這個字元還沒有插入樹中,所以就要插入, * 6.如果其孩子結點的count 值不為0,那就就直接count ++ 就可以了 * 7.無論存不存在,插入操作還是要繼續下一個字元的,所以 index = tree[index].next[ch] * 記住 tree[n].next[i] 中,i 表示的字元,next[i]是指標,指向其孩子結點為i 的指標,其值就是字元i 結點在tree[] 中的索引值 * * * 字典樹的查詢 * * 1. 遍歷單詞,對於第一個字元從樹根開始查詢 ,檢視當前結點的 ch 孩子結點裡面count 是否為1 ,即 tree[tree[index].next[ch]].count 是否為1 * 2. 如果為1 ,則表明此字元存在,向下遍歷,如果為1,則表示不存在,返回 * 3. 向下遍歷為 index = treee[index].next[ch] ,這樣會指向其孩子結點 * * * * 字元樹的刪除 * 1. 如果單詞在樹中,那麼遍歷單詞,如果於單詞的每個字元找到在樹中的位置 ,將其對應結點中的count-- * 2. index = tree[index].next[ch]; * */