前缀树

37 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

保管元素的类

public static class Node{
    public int pass;
    public int end;
    public Node[] next;
    public Node(){
        pass = 0;
        end = 0;
        next = new Node[26];
    }
}

这个类是用于保存元素的,一个字符串里面的一个字符是什么,都可以用这个代替

前缀树实现

public static class Trie{
    public Node root;

这个就是前缀树里面的属性。

构造器

    public Trie(){
        root = new Node();
    }

用来初始化root

添加

    public void insert(String str){
        if(str == null){
            return;
        }
        char[] word = str.toCharArray();
        //创建一个零时变量来代替root
        Node help = root;
        //每一次增加操作我们都要让头元素先++
        help.pass++;
        //这个循环就是遍历了字符串里面的每一个字符,为每个数创建一个自己的node
        //如果已经有一个node的话,就把pass++
        //然后让root去下一个地方
        for(int i = 0;i<word.length;i++){
            if(help.next[word[i] - 'a'] == null){
                help.next[word[i] - 'a'] = new Node();
            }
            help.next[word[i] - 'a'].pass++;
            help = help.next[word[i] - 'a'];
        }
        //遍历完之后,最后一个元素要把end++
        help.end++;
    }

删除

    public void delete(String str){
    //在删除的时候我们先要查找一下这个字符串是否存在
        if(search(str) != 0){
            char[] word = str.toCharArray();
            Node help = root;
            int index = 0;
            //遍历字符串,然后把经历过的pass--
            while(index < word.length){
                help.pass--;
                help = help.next[word[index] - 'a'];
                index++;
            }
            //最后一个元素的end--。pass也要--。
            help.end--;
            help.pass--;
            //如果end = 0表示这个字符串没有了,那就要全部删除
            if(help.end == 0){
                help = null;
            }
        }
    }

这种删除其实是会有内存问题的所以应该写下面的这个,具体是什么导致的,大家可以想一想

public void delete(String str){
    if (search(str) != 0) {
        char[] word = str.toCharArray();
        Node node = root;
        node.pass--;
        int path = 0;
        for (int i = 0; i < word.length; i++) {
            path = word[i] - 'a';
            if (--node.next[path].pass == 0) {
                node.next[path] = null;
                return;
            }
            node = node.next[path];
        }
        node.end--;
    }
}

查看有多少个字符串是以pre字符串为开头的

    public int prefixNumber(String pre){
        if(pre == null){
            return 0;
        }
        char[] word = pre.toCharArray();
        Node help = root;
        int index = 0;
        while(index < word.length){
            help = help.next[word[index] - 'a'];
            if(help == null){
                return 0;
            }
            index++;
        }
        return help.pass;
    }

就是顺着字符串找,最后返回那个元素的pass值

查找字符串有多少个

    public int search(String str){
        if(str == null){
            return 0;
        }
        char[] word = str.toCharArray();
        Node help = root;
        int index = 0;
        while(index < word.length){
            help = help.next[word[index] - 'a'];
            if(help == null){
                return 0;
            }
            index++;
        }
        return help.end;
    }
}

这个就是查找了,最后返回end值。

以上就是前缀树的全部内容了。