trie 字典树 前缀树

trie 字典树 前缀树

  • 又称为单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串,所以经常被搜索引擎系统用于文本词频统计。优点是:利用字符串的公共前缀来减少查询时间,最大限度的减少无谓的字符串比较,查询效率比哈希树高

  • 根节点不包含字符,除根节点外每一个节点都只包含一个字符; 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串; 每个节点的所有子节点包含的字符都不相同

  • 注意:对于Trie来说,其实还有一个重要的时间开销。由于Trie消耗的空间比较大(每个节点会有若干个指针),所以给这些承载指针的空间(TreeMap,HashMap或者数组)开辟内存也是一个额外的时间消耗

  • 节点进行包装:

    private class Node{
            public boolean isWord;
            public TreeMap<Character,Node> next;
            public Node(boolean isWord)
            {
                this.isWord = isWord;
                next = new TreeMap<>();
            }
            public Node()
            {
                this(false);
            }
        }
    
  • 添加:

      //向树中添加一个新的单词word
        public void add(String word)
        {
            Node cur = root;
            for (int i = 0; i < word.length(); i++) {
                char c = word.charAt(i);
                if(cur.next.get(c)==null)
                {
                    cur.next.put(c,new Node());
                }
                cur = cur.next.get(c);
            }
            if(!cur.isWord){
                 cur.isWord = true;
                 size++;
            }
        }
    
  • 包含

      //查询单词是否存在在树中
        public boolean contains(String word){
            Node cur = root;
            for (int i = 0; i <word.length() ; i++) {
                char c  = word.charAt(i);
                if(cur.next.get(c)==null)
                    return false;
                cur = cur.next.get(c);
            }
            return cur.isWord;
        }
    
  • 前缀搜索

     //前缀搜索
        public boolean isPrefix(String prefix)
        {
            Node cur = root;
            for (int i = 0; i < prefix.length(); i++) {
                char c = prefix.charAt(i);
                if(cur.next.get(c) == null)
                    return false;
                cur = cur.next.get(c);
            }
            return true;
        }
    
  • 总体代码

    package 数据结构.Trie;
    import jdk.nashorn.api.tree.ReturnTree;
    
    import java.util.TreeMap;
    public class Trie {
        private class Node{
            public boolean isWord;
            public TreeMap<Character,Node> next;
            public Node(boolean isWord)
            {
                this.isWord = isWord;
                next = new TreeMap<>();
            }
            public Node()
            {
                this(false);
            }
        }
        private Node root;
        private int size;
        public Trie(){
            root = new Node();
            size = 0;
        }
        //获得树中单词数量
        public int getSize()
        {
            return size;
        }
        //向树中添加一个新的单词word
        public void add(String word)
        {
            Node cur = root;
            for (int i = 0; i < word.length(); i++) {
                char c = word.charAt(i);
                if(cur.next.get(c)==null)
                {
                    cur.next.put(c,new Node());
                }
                cur = cur.next.get(c);
            }
            if(!cur.isWord){
                 cur.isWord = true;
                 size++;
            }
        }
        //查询单词是否存在在树中
        public boolean contains(String word){
            Node cur = root;
            for (int i = 0; i <word.length() ; i++) {
                char c  = word.charAt(i);
                if(cur.next.get(c)==null)
                    return false;
                cur = cur.next.get(c);
            }
            return cur.isWord;
        }
        //前缀搜索
        public boolean isPrefix(String prefix)
        {
            Node cur = root;
            for (int i = 0; i < prefix.length(); i++) {
                char c = prefix.charAt(i);
                if(cur.next.get(c) == null)
                    return false;
                cur = cur.next.get(c);
            }
            return true;
        }
    }
    
    

猜你喜欢

转载自blog.csdn.net/weixin_42479155/article/details/89785913