Trie树

Trie

 

上图表示一个trie树,有abc,abcd,abd,b,bcd,efg,hii七个字符串,红色点代表为一个字符串的最后一个字符。

trieTree

上图同样表示一个trie树,有abc,d,da,dda四个字符串,字符串尾部同样进行了标记。

已知n个由小写字母构成的平均长度为10的字符串,判断其中是否存在某个串为另一个串的前缀子串,有三种方法:

1、遍历字符串集合,对于遍历的每两个字符串,判断其中一个是否为另一个的前缀子串,时间复杂度为O(n^2)。

2、使用hash,对于每一个字符串的所有前缀子串,进行hash,对于完整的字符串进行标记,然后再进行查询。其中建立hash的时间复杂度为O(n*len),而查询的时间复杂度为O(n)。

3、使用trie树,很自然的一个数据结构,可以建立的同时进行查询,其中建立trie树的时间复杂度为O(n*len),实际查询的复杂度为O(len)。

 

Trie树的实现代码,数据结构是上述第二幅图

#include <iostream>
using namespace std;

const int BranchNum=26;

struct Trie_Node
{
	bool isStr;//标记是否为完整字符串
	Trie_Node* next[BranchNum];
	Trie_Node()
	{
		isStr=false;
		for(int i=0;i<BranchNum;++i)
			next[i]=NULL;
	}
};


class Trie
{
public:
	Trie();
	void insert(const char* word);
	bool search(const char* word);
	void deleteTrie(Trie_Node* root);
private:
	Trie_Node* root;
};

Trie::Trie()
{
	root=new Trie_Node;
}

void Trie::insert(const char* word)
{
	Trie_Node* current=root;
	while(*word)
	{
		if(current->next[*word-'a']==NULL)
		{
			current->next[*word-'a']=new Trie_Node;
		}
		current=current->next[*word-'a'];
		word++;
	}
	current->isStr=true;
}

bool Trie::search(const char* word)
{
	Trie_Node* current=root;
	while(*word && current)
	{
			current=current->next[*word-'a'];
			++word;
	}
	return (current!=NULL && current->isStr);
}

void Trie::deleteTrie(Trie_Node* root)
{
	for(int i=0;i<BranchNum;++i)
		if(root->next[i])
			deleteTrie(root->next[i]);
	delete root;
}

 

参考自:http://www.ahathinking.com/archives/14.html

posted @ 2012-06-19 15:19  Cavia  阅读(272)  评论(0编辑  收藏  举报