数据结构——字典树

NO.1 定义#

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

它具体是什么样的呢?

它的点用来保存每一个节点编号,以及有无在此节点结束的字符串。

它的边用来保存字符。

从根节点到每一个子节点的路径上字符所组成的即为一个字符串。

NO.2 插入#

字典树共应用两个函数,插入和检索。

插入,顾名思义即为在字典树中插入一个字符串,从根节点出发,根据字符串上的每一个字符向下搜,如果指向空则另开边存储字符。

需要注意,我们需运用一个数组来记录此节点是否是一个字符串的末尾,不然无法判断在字典树上是否存在此字符串。

Code

void Insert(char *str){//将字符串以指针形式传入,操作时直接影响实参
	int p=1,len=strlen(str);
	for(int i=0;i<len;i++){
		int ch=str[i]-'a';
		int q=Trie[p][ch];
		if(!q){//判断是否存在保存当前字符的边
			Trie[p][ch]=q=++cnt;
		}
		p=q;
	}
	End[p]++;//保存结尾
}

NO.3 检索#

检索,指判断字典树中是否存在一个字符串。

依旧从根节点出发,根据字符串上的每一个字符向下搜,如果没有边对应字符串中的字符或搜到末尾没有标记,则说明没有此字符串在字典树中,反而有之。

Code

bool search(string s){//依旧传入字符串地址
    int p=1,len=s.length();
    for(int i=0;i<len;i++){
        int ch=s[i]-'0'; 
        p=Trie[p][ch];
        if(!p){//判断有无此边
                return 0;
	}
    }
    return en[p];//判断此边是否是一个字符串结尾
}

NO.4 例题#

The XOR-longest Path#

Link

题目描述#

给定一棵 n 个点的带权树,求树上最长的异或和路径。

输入格式#

第一行一个整数 n ,接下来 n1 行每行三个整数 u,v,w ,表示 u,v 之间有一条长度为 w 的边。

输出格式#

输出一行一个整数,表示答案。

样例#

样例输入

4
1 2 3
2 3 4
2 4 6

样例输出

7

思路#

题目解释的很清楚,求树上一段路径的数异或的最大值。

因为 aa=0

所以我们可求得根节点到每一节点异或值,设为 da

设要求的路径端点为 x,y,则路径上的异或值为 dxdy

根据每两个端点的异或值的二进制数建字典树,因异或,每一数位的数字相反才为 1,则每次判断字符时去与它想法的一边即可。

Code
void Insert(ll x){
	ll p=1;
	for(int i=30;i>=0;i--){
		ll ch=x>>i&1;
		if(!Trie[p][ch]){
			Trie[p][ch]=++cnt;
		}
		p=Trie[p][ch];
	}
	End[p]=1;
}

ll Search(ll x){
	ll p=1,ans=0,de=30;
	for(int i=30;i>=0;i--){
		ll ch=x>>i&1;
		if(Trie[p][!ch]){
			ans|=(1<<i);
			p=Trie[p][!ch];
		}
		else{
			p=Trie[p][ch];
		}
	}
	return ans;
}

Finally#

精简版总结

例题还可能会补充。。。

posted @   faith_xy  阅读(75)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示