To_Heart—总结——字典树

直到今天,我才知道原来字典树也是数据结构

字典树(Trie)是一种用于实现字符串快速存储和检索的多叉树结构。Trie的每个节点都拥有若干个字符指针(可理解为若干条单个字符的边),若在插入或检索字符串时扫描到一个字符c,就沿着当前节点的c字符指针,走向该指针指向的节点。

不好理解?

上图就展示了一棵字典树,其中的每一条与根节点相连的链都是一个字符串,可以发现,我们利用各个字符串之间的相同前缀,而不是每一个字符串都去开一个数组,大大减小了空间复杂度,同时使检索字符更加方便。

接下来,我向大家介绍字典树的两种基本操作。

初始化

首先,要初始化。。。

一颗空的字典树中仅包含一个节点,且该节点的所有字符指针指向空(如果字符串中只有小写字母,字符指针就有26个)。

int Trie[100005][26+5]={
    
    };	//初始化直接全部指向空
int tot=1;		//tot为当前节点编号

操作1:添加

如何在字典树中添加一个字符?

当需要插入一个字符串S时,我们令一个指针P起初指向根节点(可以理解为以根节点为起点,做好扫描准备),然后依次遍历S中的每一个字符c:

  1. 若P的c字符指针指向一个已经存在的节点Q,则令P=Q。
  2. 若P的c字符指针指向空,则新建一个节点Q,令P的c字符指针指向Q,然后令P=Q。

当S中的字符扫描完毕时,在当前节点P上标记它是一个字符串的末尾。

下图则是该操作的具体事例。

在这里插入图片描述
代码如下:

void Insert(){
    
    
	char s[1005];
	scanf("%s",s+1);
	int len=strlen(s+1);   				//输入字符串 
	int p=1;							//p为当前节点编号,一开始均指向根节点 
	for(int i=1;i<=len;i++){
    
    
		if(!Trie[p][s[i]-'a']){
    
    
			Trie[p][s[i]-'a']=++tot;	//如果当前的字符指针指向空,则新建一个节点Q,令P的c字符指针指向Q。 
		}
		p=Trie[p][s[i]-'a'];			//进入下一个节点。 
	}
	End[p]=1;							//标记以当前节点结尾的单词 
}

操作2:查找

当需要检索一个字符串S在Trie中是否存在时,我们令一个指针P起初指向根节点,然后依次遍历S中的每个字符c:

  1. 若P的c字符指针指向空,则说明S没有被插入过Trie中,return 0;结束检索。
  2. 若P的c字符指针指向一个已经存在的节点Q,则令P=Q。

当S中的字符扫描完毕时,若当前节点P被标记为一个字符串的末尾,则说明S在Trie中存在,否则说明S没有被插入过Trie

直接放代码吧。。。

bool Find(* char s){
    
    				//读入一个字符串 
	int p=1;
	int len=strlen(s+1);
	for(int i=1;i<=len;i++){
    
    
		if(!Trie[p][s[i]-'a'])		//如果指针指向空,说明没有该字符串 
			return 0;				
		p=Trie[p][s[i]-'a'];		//否自继续找 
	}
	return End[p];					//判断是否结尾 
} 

Guess you like

Origin blog.csdn.net/xf2056188203/article/details/113891933