数据结构---Trie树

Trie树

Trie树,又称字典树,单词查找树,顾名思义,字典树与字典很相似,是一种经常用于统计,排序,保存大量字符的数据结构。Trie树利用字符串的公共前缀来节约存储空间,因此其效率很高,所以在在字符串查找、前缀匹配等中应用很广泛。不过其高效率是以花费大量空间为代价的。

Trie树的构造(以26小写字母为例)

Trie树数据结构定义

#define MAX 10
struct Trie{
    Trie *next[MAX]; //分支数
    int v;//以当前字符串为前缀的个数
};

其中next 为存放着节点指向孩子节点的指针。v 可以根据自己的目的变化,这里可以是以 到当前节点的为前缀的字符串的个数。

Trie树的操作

插入操作

插入操作可以理解为建树的过程,可以这样理解:

假设Trie的根节点是root,当前字符串为str,当前节点指针为p,初始为root
    遍历str:
        若p->next[str[i]-'a']为空,则说明之前没有此前缀,需要新建节点q,     更新p->next[], 同时更新p
        若不为空, 则说明之前已经有了该前缀,只需要更新p以及 计数  

具体代码如下:

void createTrie(char *str)
{
    int len=strlen(str);
    Trie *p=root,*q;
    for(int i=0; i<len;i++)
    {
        int id= str[i]-'a';
        if(!p->next[id])
        {

            q=(Trie*) malloc(sizeof(Trie));
            q->v=1;
            for(int j=0; j<MAX; j++)
            {//更新节点的next指针
                q->next[j]=NULL;
            }
            p->next[id]=q;
            p=p->next[id];
        }
        else
        {

            p->next[id]->v++;//更新计数
            p=p->next[id];
        }
    }
}

查找操作

(1) 每次从根结点开始一次搜索;
(2) 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;
(3) 在相应的子树上,取得要查找关键词的第二个字母,进一步选择对应的子树进行检索。 
(4) 迭代过程……
(5) 在某个结点处,关键词的所有字母已被取出,则读取附在该结点上的信息,即完成查找。 否则查找失败.

具体查找代码如下:

int findTrie(char *str)
{//返回以当前前缀的个数,复杂度O(len)
    int len=strlen(str);
    Trie * p= root;
    for(int i=0; i<len; i++)
    {
        int id=str[i]-'a';
        p=p->next[id];
        if(!p) return 0;
    }
    return p->v;
}   

删除操作

本来删除可以不用我们完成的,不过在有些情况下, 需要动态的不断的建立树,就需要我们手动释放内存了,对Trie树的删除一般指删除整棵树。
直接递归 由下到上释放对象即可.

void del(Trie *T)
{
    if (!T) return;
    for(int i=0; i<MAX; i++)
    {
        if(T->next[i]) del(T->next[i]);
    }
    free(T);
}

字典树的基本介绍就是这些了,后面做几道ACM题巩固巩固。

    原文作者:Trie树
    原文地址: https://blog.csdn.net/shomy_liu/article/details/43817325
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注