数据结构与算法 - 前缀树

这篇博客介绍了前缀树(Trie)的概念和用途,包括如何存储字符串以及查询字符串出现次数和作为前缀的次数。文章给出了Java实现前缀树的代码示例,包括两个不同的节点类实现,展示了插入、查询和删除字符串的操作。此外,还讨论了前缀树在字符串查找和统计中的高效性。

前缀树

1. 概念

(1)单个字符串中,字符从前到后加到一棵多叉树上
(2)字符放在路上,节点上有专属的数据项(通常是pass和end值)
(3)所有样本都这样添加,如果没有路就新建,有路就复用
(4)沿途节点的pass值增加1,每个字符结束时来到的节点end值增加1
所有字符串里包含的字符数为N,为这N个字符都建一个节点,时间复杂度为O(N)
前缀树

2. 用法

(1)查询加入了某个字符串几次? 看e值或者无路就代表没加入。例如“ab”字符串被加入了1次,“cd”字符串没有加入过。
(2)查询某个字符是多少个字符串的前缀,看P值,例如a是三个字符串的前缀。
使用List

public class Node {
    public int path;
    public int end;
    public Node[] nodeList;

    public Node(){
        //We have 26 character, so set the size of nodeList to 26
        this.nodeList = new Node[26];
    }
}

package test;

public class StringTree {
    private Node root;

    public StringTree() {
        this.root = new Node();
    }

    public void insert(String str) {
        if (str != null && str.length() > 0) {
            char[] charList = str.toCharArray();
            Node tmp = root;
            tmp.path++;
            int index;
            for (char value : charList) {
                index = value - 'a';
                if (tmp.nodeList[index] == null) {
                    tmp.nodeList[index] = new Node();
                }
                tmp = tmp.nodeList[index];
                tmp.path++;

            }
            tmp.end++;
        }
    }

    public int getTheNumberOfString(String str) {
        int result = 0;
        if (str != null && str.length() > 0) {
            char[] charList = str.toCharArray();
            Node tmp = root;
            int index,count=0;
            for (char value : charList) {
                index = value - 'a';
                if(tmp.nodeList[index]!=null){
                    tmp = tmp.nodeList[index];
                    count++;
                }else{
                    break;
                }
            }
            if (count == charList.length) {
                result = tmp.end;
            }
        }
        return result;
    }

	public void deleteString(String str){
        if(str!=null && str.length()>0){
            char[] charList = str.toCharArray();
            Node tmp = root;
            int index;
            tmp.path--;
            for(char value : charList){
                index = value - 'a';
                if(--tmp.nodeList[index].path==0){
                	tmp.nodeList[index]=null;//Free up memory
                    return;
                }
                tmp = tmp.nodeList[index];
            }
            tmp.end--;
        }
    }
}

数据结构2:

public class Node1 {
    public int path;
    public int end;
    public Map<Integer,String> nodeList;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值