字典树,了解一下
最近做leetcode上一道难题遇到了字典树,然后了解到TreeMap,但是不了解实现,反正最后看代码直接看懂了,就是一个26叉树。然后我直接上图,上代码了。
下面是先序遍历
就是在一个根节点建立26个引用,代码的变量直接使用引用数组。没有子节点的直接为null
package com.zzj.leetcode; public class Trie{ private int SIZE=26; private TrieNode root;//字典树的根 Trie(){ root=new TrieNode(); } private class TrieNode{ private int num;//有多少单词通过这个节点 由根节点到该节点组成的字符串模式出现的次数 private TrieNode[] son;//所有的儿子节点 private boolean isEnd;//是不是最后一个节点 private char val;//节点的值 TrieNode(){ num=1; son=new TrieNode[SIZE];//在此处相当于创建了一个容器 isEnd=false;//是否是单词结束的节点 } }//字典树节点 public void insert(String str){ if( str==null||str.length()==0){ return; } TrieNode node=root; char[] letters=str.toCharArray(); for(int i=0,len=str.length();i<len;i++){ int pos=letters[i]-'a'; if(node.son[pos]==null){ node.son[pos]=new TrieNode(); node.son[pos].val=letters[i]; }else{ node.son[pos].num++; } node=node.son[pos]; } node.isEnd=true;//迭代结束时候所在的节点为true } //计算单词前缀的数量.....NB啊尼玛 public int countprefix(String prefix){ if(prefix==null||prefix.length()==0){ return -1;//传递进来的字符串只要长度为0或者前缀为null,则返回-1 } TrieNode node=root;//将根节点传递过来,根节点并未被修改过 char[] letters=prefix.toCharArray();//将字符串打散成char数组 for(int i=0,len=prefix.length();i<len;i++){//然后遍历前缀字串数组 int pos=letters[i]-'a'; if(node.son[pos]==null){ return 0;//只要某个字符在字典数的某个路径是空的,则返回0 }else{ node=node.son[pos];//如果这个路径有,则给node赋新的值 } } return node.num; } //打印指定前缀的单词 public String hasPrefix(String prefix){ if(prefix==null||prefix.length()==0){ return null; } TrieNode node=root; char[] letters=prefix.toCharArray(); for(int i=0,len=prefix.length();i<len;i++){ int pos=letters[i]-'a'; if(node.son[pos]==null){ return null; }else{ node=node.son[pos]; } } preTraverse(node,prefix); return null; } public void preTraverse(TrieNode node,String prefix){ if(!node.isEnd){ for(TrieNode child:node.son){ if(child!=null){ preTraverse(child,prefix+child.val);//链接字符串??? } } } System.out.println(prefix); } public boolean has(String str){ if(str==null||str.length()==0){ return false; } TrieNode node=root; char[] letters=str.toCharArray(); for(int i=0,len=str.length();i<len;i++){ int pos=letters[i]-'a'; if(node.son[pos]!=null){ node=node.son[pos]; }else{ return false; } } return node.isEnd; } public TrieNode getRoot(){ return this.root; } public void preTraverse(TrieNode node) { if(node!=null) { System.out.print(node.val+"-"); for(TrieNode child:node.son) { preTraverse(child); } } } public static void main(String args[]){ Trie tree = new Trie(); String[] strs={"abc","xasdsa","dsad","dsada","dasdas","dsadsa","dsas"}; String[] prefix={"ab","xas","ds","d","dasda","dsa"}; for(String str:strs){ tree.insert(str); }//建立字典树 System.out.println(tree.has("has")); tree.preTraverse(tree.getRoot()); for(String pre:prefix){ int num=tree.countprefix(pre); System.out.println(pre+""+num); } } }
运行结果: