zoukankan      html  css  js  c++  java
  • 【数据结构】Trie树

    数据结构——Trie树

    概念

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

    Trie树的结构如下图所示:

    Trie树中的节点数据结构如下:

    • 当前字符
    • 子节点数组(如果全为小写字母的话,子节点数量固定为26个,根据字符来确定在数组中的位置,如'a'的下标为0,'z'为25)
    • 是否为一个单词的结尾(标红的节点)
    • 出现次数

    特点:root节点不存储字符。

    代码实现

    public class Trie {
        private Node root;
        class Node{
            int count;
            char ch;
            Node[] child;
            boolean isEnd;
    
            public Node() {
                this.count = 1;
                this.child = new Node[26];
                this.isEnd = false;
            }
        }
    
    
        /** Initialize your data structure here. */
        public Trie() {
            this.root = new Node();
        }
    
        /** Inserts a word into the trie. */
        public void insert(String word) {
            if (null == word || "".equals(word)) return;
            if (this.search(word)) return;
    
            Node cur = this.root;
            char[] chars = word.toCharArray();
            for(char c : chars) {
            	//根据字符找到在子节点数组中的下标
                int pos = c - 'a';
                Node child = cur.child[pos];
                //如果子节点没有被初始化过则初始化,并设置其字符
                if (child == null) {
                    cur.child[pos] = new Node();
                    cur.child[pos].ch = c;
                }
                cur.count++;
                //更新cur节点为子节点,向下递归
                cur = cur.child[pos];
            }
    
            //最后一个字符的节点
            cur.isEnd = true;
        }
    
        /** Returns if the word is in the trie. */
        public boolean search(String word) {
            if (null == word || "".equals(word)) return true;
            Node cur = this.root;
            char[] chars = word.toCharArray();
            for (char c : chars) {
                int pos = c - 'a';
    
                Node node = cur.child[pos];
                if (node == null) return false;
    
                cur = node;
            }
            return cur.isEnd;
        }
    
        /** Returns if there is any word in the trie that starts with the given prefix. */
        public boolean startsWith(String prefix) {
            if (null == prefix || "".equals(prefix)) return true;
            Node cur = this.root;
            char[] chars = prefix.toCharArray();
            for (char c : chars) {
                int pos = c - 'a';
                Node node = cur.child[pos];
                if (node == null) return false;
                cur = node;
            }
    
            return cur.count > 0;
        }
    
        public static void main(String[] args) {
            Trie trie = new Trie();
    
            trie.insert("a");
            trie.insert("adc");
            trie.insert("aer");
    
            System.out.println(trie.search("a"));
            System.out.println(trie.startsWith("a"));
        }
    }
    

    结果:

    208. Implement Trie (Prefix Tree)

    超过94%,感觉还不错~

  • 相关阅读:
    [转]Ctags 使用细节
    [转]ctags的使用及相关参数介绍
    [转]ubuntu面板 图标缺失的处理办法
    压缩空气动力自行车
    丰富的开发体验和激动人心的用户体验:XAML
    发现一个控件,介绍一下
    智能电视的设想(发明畅想)
    裹脚布
    整理了《类库开发的设计准则》一文
    关于设计器类程序的模型,先记录下来,怕以后忘记了
  • 原文地址:https://www.cnblogs.com/puyangsky/p/7049047.html
Copyright © 2011-2022 走看看