字符串---前缀树、字典树、Trie树的实现

关键点:

1、节点类的构建,通过一个数组记录下一个节点及路径

2、注意path==0、end==0的含义

//字典树、前缀树的实现
/*是一种树形结构,优点是利用字符串的公共前缀来节约存储空间
 * */
 class TrieNode{
	public int path;//表示有多少个单词共用这个节点
	public int end;//表示有多少个单词以这个节点结尾
	public TrieNode[] map;
	//key表示该节点的一条字符路径,value表示字符路径指向的节点
	
	public TrieNode() {
		path = 0;
		end  = 0;
		map = new TrieNode[26];
	}
}

 class Trie{
	private TrieNode root;
	public Trie() {
		root = new TrieNode();
	}
	//添加word,可重复添加
	public void insert(String word) {
		if(word == null) {
			return;
		}
		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) {
				node.map[index] = new TrieNode();
			}
			node = node.map[index];
			node.path++;
		}
		node.end++;
	}
	//查询word是否在trie树中
	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];
		}
		//没有单词通过最后一个节点
		if(node.end == 0) {
			return false;
		}
		return true;
	}
	//删除word,如果word添加过多次,仅删除一个
	public void delete(String word) {
		if(search(word)) {
			char[] chs = word.toCharArray();
			int index = 0;
			TrieNode node = root;
			for(int i = 0;i < chs.length;i++) {
				index = chs[i]-'a';
				if(node.map[index].path-- == 1) {
					node.map[index] = null;//该路径没有单词走过
				}
				node = node.map[index];
			}
			node.end--;
			
		}
	
	}
	
	//返回以字符串pre为前缀的单词数量
	public int prefixNumber(String pre) {
		if(pre == null) return 0;
		TrieNode node = root;
		int index = 0;
		char[] chs = pre.toCharArray();
		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;
	}
	
	
}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值