算法5——trie树(字典树)

主要是利用树方面的知识构造一个所谓的字典树实现首先输入某字符集然后输入一个 字符串前缀查询字符集中有此前缀的字符串数目,程序相对简单主要就是两个子函数其一是构造函数insert,另一个是查询函数search,函数本身类似于链表的构造与遍历。

trie树的实现比较简单。它使在字符串集合中查找某个字符串的操作的复杂度降到最大只需O(n),其中n为字符串的长度。trie是典型的将时间置换为空间的算法,好在ACM中一般对空间的要求很宽松。trie的原理是利用字符串集合中字符串的公共前缀来降低时间开销以达到提高效率的目的。 它具有以下性质:

  • 根结点不包含任何字符信息;
  • 如果字符的种数为n,则每个结点的出度为n(这样必然会导致浪费很多空间,这也是trie的缺点,还没有想到好点的办法避免);
  • 查找,插入复杂度为O(n),n为字符串长度。

PD:

给定一个字符串集合,然后每次询问时给出一个字符串,问以该字符串为前缀的字符串在集合中有多少个。

trie版:

#include<iostream>
using namespace std;
const int kind=26;
struct Treenode 
{
	int count;
	Treenode *next[kind];
	Treenode()
	{
	 count=1;
	 for(int i=0;i<kind;i++)
		 next[i]=NULL;
	}
};
void insert(Treenode *&root,char* word);
int search(Treenode *root,char *word);
int main()
{
	 
	char word[20],ask[20];
	Treenode *root=NULL;
	cout<<"第1个:";
	int g=2;
	while(gets(word))
	{
		
		if(word[0]=='\0')
			break;
		cout<<"第"<<g<<"个:";
		g++;
		insert(root,word);
	}
	cout<<"Search……"<<endl;
	while(gets(ask))
	{
		cout<<search(root,ask)<<endl;
		if(ask[0]=='\0')
			break;
	}

    return 0;
}
void insert(Treenode *&root,char *word)
{
	Treenode *location=root;
	int i=0,branch=0;
	if(location==NULL)
	{
		location=new Treenode();
		root=location;
	}
	while(word[i])
	{
		branch=word[i]-'a';
		if(location->next[branch])
			location->next[branch]->count++;
		else location->next[branch]=new Treenode();
		i++;
		location=location->next[branch];
	}
}
int search(Treenode *root,char *word)
{
	Treenode *location=root;
	int i=0, branch=0,ans;
	if(location==NULL) return (0);
	while(word[i])
	{
	   branch=word[i]-'a';
	   if(!location->next[branch]) break;
	   i++;
	   location=location->next[branch];
	   ans=location->count;
	}
	return ans;
}

trie树(字典树)-HDU1251

点赞