前缀树

建树,数据存储在路径上

可以查询 是否包含前缀为 xx 的字符串
例如 查询前缀是否包含 be 的字符串,可以查到
但是无法查询确定的字符串,例如查询字符串是否含有 be,无法查询,那么需要改进
也即,可以在节点位置上添加一条信息,这条信息保存了 有多少个字符串以当前字母结尾的
例如 在插入 bef 字符串的时候,b路径的尾端节点置 0 ,因为没有任何一个字符串以 b 结尾
同样,e 尾端节点也是0,但是 f 的尾端节点是 1 ,因为有一个字符串 bef 是以 f 结尾的
这样,我们就可以精确的知道,哪个字符串是存在的
我们可以再在节点处加一个数据项,来表示经过某节点多少次,例如 abd 串 中的 b 节点,每到达一次 b 节点,我们就让 这个数据项 + 1,这样,我们就能知道 以 ab 为前缀的字符串有多少个

package 前缀树;

public class TrieTree {

private TrieNode root;

public TrieTree() {
	root = new TrieNode();
}

/**
 * 插入
 * 
 * @param word
 */
public void insert(String word) {
	if(word == null) return;
	
	char[] chars = word.toCharArray();
	TrieNode node = root;
	int index = 0;
	for(int i=0;i<chars.length;i++) {
		// 例如 当前节点 是a  那么  index = 0
		//如果当前节点 是 z 那么 index = 25
		index = chars[i] - 'a';
		//如果 当前节点的 nexts[index] 不存在,那么说明没有这条路,则建路
		if(node.nexts[index] == null) {
			node.nexts[index] = new TrieNode();
		}
		node = node.nexts[index];
		node.path++;
	}
	node.end++;
}

/**
 * 查询插入了几次
 * 
 * @param word
 * @return
 */
public int search(String word) {
	if(word == null) return 0;
	
	char[] chars = word.toCharArray();
	TrieNode node = root;
	int index = 0;
	for(int i=0;i<chars.length;i++) {
		// 例如 当前节点 是a  那么  index = 0
		//如果当前节点 是 z 那么 index = 25
		index = chars[i] - 'a';
		//如果 当前节点的 nexts[index] 不存在,那么说明没有这条路,则建路
		if(node.nexts[index] == null) {
			return 0;
		}
		node = node.nexts[index];
	}
	return node.end;
}

/**
 * 查找  前缀出现了机次
 * 
 * @param pre
 * @return
 */
public int prefixNumber(String pre) {
	if(pre == null) return 0;
	
	char[] chars = pre.toCharArray();
	TrieNode node = root;
	int index = 0;
	for(int i=0;i<chars.length;i++) {
		index = chars[i] - 'a';
		if(node.nexts[index] == null) {
			return 0;
		}
		node = node.nexts[index];
	}
	//path 是到达了机次  即前缀的数量  
	return node.path;
}

/**
 * 删除
 * 
 * @param word
 */
public void delete(String word) {
	if(search(word) == 0) return;
	
	char[] chars = word.toCharArray();
	TrieNode node = root;
	int index = 0;
	for(int i=0;i<chars.length;i++) {
		index = chars[i] - 'a';
		//如果  node 的path 已经是 0 了  就说明  这个节点下面的链  只出现过一次,那么直接可以把下面的节点删除
		if(node.nexts[index].path == 0) {
			node.nexts[index] = null;
			return;
		}
		node = node.nexts[index];
	}
	node.end--;
}

}

class TrieNode {
//有多少节点到达过这个节点
int path;
//有多少节点以当前节点结尾
int end;
//表示 当前节点共 多少条路
//本类 默认 路最多有 26条,也就是说 一个节点 的下面的路 最多由 a,b,c,…,z组成 共26条
TrieNode[] nexts;

public TrieNode() {
	path = 0;
	end = 0;
	nexts = new TrieNode[26];
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值