Trie树学习笔记

  字典树(Trie树),可以将之归为高级数据结构吧,黑书上把Trie树和线段树一起讲的。之所以叫它字典树,大概是因为它的结构太像字典了。

就像这张图片:

由字符串 abcd、abd、bcd、efg、hi。建成的Trie树如上图所示(Trie树大概的结构一看就能理解);


Trie树的主要操作:

1、建立新节点(姑且算是一样吧);

2、插入(建树);

3、查找(与树中的字符串匹配,这个过程是肯快的,如果能完全匹配的时间复杂度为是O(n),n = strlen(s)。)

Trie的实现:

1、结构体定义:

struct node
{
int flag; //标记
node * next[26]; //存放字符,建立于链表类似的关系
};

2、新节点的建立:

/*动态分配内存*/
node
* newnode()
{
int i;
node
* p = new node; // c语言用(node * )malloc(sizeof(node), 这里是动态分配内存,时间上可能消耗的多一些
p->flag = 0;
for(i = 0; i < 26; i++)
p
->next[i] = NULL;
return p;
}

/*静态分配内存*/
node T[
1000000];
int t = 0;
node
* newnode()
{
int i;
node
* p = &T[t++]; //静态分配
p->flag = 0;
for(i = 0; i < 26; i++)
p
->next[i] = NULL;
return p;
}

3、插入:

void insert(node * root, char *s)
{
node
* p = root;
int i, len = strlen(s), t;
for(i = 0; i < len; i++)
{
t
= s[i] - 'a';
if(p->next[t] == NULL)
p
->next[t] = newnode(); //分配新内存
p = p->next[t];
}
p
->flag = 1; //插入完成,在最后一个字符上做标记具体到题目时可能就会有很多变化
}

4、查找:

int search(node * root, char *s)
{
node
* p = root;
int i, t, len = strlen(s);
for(i = 0; i < len; i++)
{
t
= s[i] - 'a';
if(p->next[t] == NULL) //不匹配直接返回0,这个可以比数组模拟省很多时间
return 0;
p
= p->next[t];
}
if(p->flag) //刚好与原来插入的字符串相同
return 1;
return 0;
}

5、小结:

Trie的操作就这几个,但是对查找和插入时字符串的预处理很灵活,比如HDU 1075,HDU 1247(都是很简单的题,仔细想想就出来了)。

这里是两题的题解:

HDU 1247 http://www.cnblogs.com/vongang/archive/2011/08/21/2148615.html

HDU 1075 http://www.cnblogs.com/vongang/archive/2011/08/21/2147992.html



posted @ 2011-08-22 09:00  AC_Von  阅读(667)  评论(0编辑  收藏  举报