前缀树的相关概念和增删查实现

百度百科:

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

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

 key:查询次数跟样本数量无关,跟要查询的字符串长度有关

【Code】

public class TrieTree {
    //前缀树
    public static class TrieNode
    {
        public int path;
        public int end;
        public TrieNode[] map;
        public TrieNode()
        {
            path = 0;//代表从根节点到当前节点代表的前缀被多少字符串共享
            end = 0;//代表从根节点到当前节点的字符串一共存储了多少次
            map = new TrieNode[26];
        }
    }
    public static class Trie
    {
        private TrieNode root;
        public Trie()
        {
            root = new TrieNode();
        }
        public void insert(String str)
        {
            if(str==null)
                return;
            char[] chs = str.toCharArray();//将字符串化成字符数组
            TrieNode node = root;
            int index = 0;
            for(int i = 0;i<chs.length;i++)
            {
                index = chs[i] - 'a';//找到a通路的下标
                if(node.map[index]==null)//如果a通路的下标指向的节点为空,证明该路不存在
                    node.map[index] = new TrieNode();//此时创建该节点,代表搭建该路
                node = node.map[index];//往下顺
                node.path++;
            }
            node.end++;
        }
        public void delete(String str)
        {
            if(str==null)
                return;
            char[] chs = str.toCharArray();
            TrieNode node = root;
            int index = 0;
            for(int i = 0;i<chs.length;i++)
            {
                index = chs[i]-'a';
                if(node.map[index].path-- == 1)
                {
                    node.map[index] = null;
                    return;
                }
            }
            node.end--;
        }
        public boolean search(String word)
        {
            if (word == null) {
                return false;
            }
            char[] chs = word.toCharArray();
            TrieNode node = root;
            int index = 0;
            for (int i = 0; i < chs.length; i++) {
                index = chs[i] - 'a';
                if (node.map[index] == null) {
                    return false;
                }
                node = node.map[index];
            }
            return node.end != 0;
        }
        //前缀str出现的次数
        public int preCount(String pre)
        {
            if(pre==null)
                return 0;
            char[] chs = pre.toCharArray();
            TrieNode node = root;
            int index = 0;
            for(int i = 0;i<chs.length;i++)
            {
                index = chs[i] - 'a';
                if(node.map[index]==null)
                    return 0;
                node = node.map[index];
            }
            return node.path;
        }
    }
}
posted @ 2021-02-06 11:22  γGama  阅读(109)  评论(0)    收藏  举报