字典树,了解一下

最近做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);
        }
    }
}

运行结果: 

猜你喜欢

转载自www.cnblogs.com/bestzj/p/10720929.html