浅谈 trie树 及其实现

定义:又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,

如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树。

核心思想:是空间换时间.利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

三个基本性质:

1. 根结点不包含字符,除根结点外每一个结点都只包含一个字符。

2. 从根结点到某一结点,路径上经过的字符连接起来,为该结点对应的字符串。

3. 每个结点的所有子结点包含的字符都不相同。

优点:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。

缺点:如果存在大量字符串且这些字符串基本没有公共前缀,则相应的trie树将非常消耗内存。

典型应用:统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计

至于Trie树的实现,可以用数组,静态分配空间,也可以用指针动态分配

Trie树的操作

在Trie树中主要有3个操作,插入、查找和删除。一般情况下Trie树中很少存在删除单独某个结点的情况,因此只考虑删除整棵树。

假设存在字符串str(都为小写字母),Trie树的根结点为root。i=0,p=root。

typedef struct stu
{
    int n,flag;         //n记录前缀及单词的个数,flag标记单词是否存在
    struct stu *next[26];          //子节点
}node;

开辟新节点并初始化:

node* creat_node()
{
    node *p=(node *)malloc(sizeof(node));
    p->n=p->flag=0;
    memset(p->next,0,sizeof(p->next));
    return p;
}

1、插入

1)取str[i],判断p->next[str[i]-‘a‘]是否为空,若为空,则建立结点temp,并将p->next[str[i]-‘a‘]指向temp,然后p指向temp;

若不为空,则p=p->next[str[i]-‘a‘];

2)i++,继续取str[i],循环1)中的操作,直到遇到结束符‘\0‘,此时将当前结点p中的 flag 置为true。

插入并统计一个字符串

void trie_insert(node *p,char *s)
{
    int i;
    while(*s!='\0'){
        i=*s-'a';
        if(p->next[i]==0)
            p->next[i]=creat_node();
        p=p->next[i];
        s++;
        p->n++;
    }
    p->flag=1;
}

2、查找

1)取str[i],判断判断p->next[str[i]-‘a‘]是否为空,若为空,则返回false;若不为空,则p=p->next[str[i]-‘a‘],继续取字符。

2)重复1)中的操作直到遇到结束符‘\0‘,若当前结点p不为空并且 flag 为true,则返回true,否则返回false。

查找一个字符串是否存在,并返回其个数:

int trie_search(node *p,char *s)
{
    int i;
    while(*s!='\0'){
        i=*s-'a';
        p=p->next[i];
        if(p==0)
            return 0;
        s++;
    }
    return p->n;
}

3、删除

删除可以以递归的形式进行删除。

递归删除整棵树:

void trie_del(node *root)
{
    int i;
    for(i=0;i<M;i++)                     //M为子节点的个数
        if(root->next[i]!=NULL)
            trie_del(root->next[i]);
    free(root);
}

浅谈 trie树 及其实现

时间: 2024-10-08 09:55:16

浅谈 trie树 及其实现的相关文章

浅谈 trie树 及事实上现

定义:又称字典树,单词查找树或者前缀树,是一种用于高速检索的多叉树结构. 如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. 核心思想:是空间换时间.利用字符串的公共前缀来减少查询时间的开销以达到提高效率的目的. 三个基本性质: 1. 根结点不包括字符,除根结点外每个结点都仅仅包括一个字符. 2. 从根结点到某一结点,路径上经过的字符连接起来,为该结点相应的字符串. 3. 每一个结点的全部子结点包括的字符都不同样. 长处:利用字符串的公共前缀来节约存储空间,最大限度地降低无谓的字符串

浅谈数据结构-树

树是一种数据结构,其中一个元素可以有两个或者多个数据元素,具有一对多的特点,用树结构来存储文件. 树的概念 结点的度:子结点的个数.例如结点1中有3个子结点,结点1的度是3. 树的度:树的度等于所有结点度中度最高的值.结点最高的度为3,树的度为3. 叶子结点:度为0的结点,即没有子结点的结点.例如:上图中3,5,6,7,9,10. 分支结点:除了叶子结点以外的结点,即度不为0的结点.例如:上面树的分支结点为1,2,4,8. 内部结点:除了根结点以及叶子结点或在分支结点的基础之上在去掉根结点.例如

浅谈线段树

 数据结构——线段树 O.引例 A.给出n个数,n<=100,和m个询问,每次询问区间[l,r]的和,并输出. 一种回答:这也太简单了,O(n)枚举搜索就行了. 另一种回答:还用得着o(n)枚举,前缀和o(1)就搞定. 那好,我再修改一下题目. B.给出n个数,n<=100,和m个操作,每个操作可能有两种:1.在某个位置加上一个数:2.询问区间[l,r]的和,并输出. 回答:o(n)枚举. 动态修改最起码不能用静态的前缀和做了. 好,我再修改题目: C.给出n个数,n<=1000000,

浅谈数据结构-树和二叉树之间关系

树都可用二叉链表作为存储结构,对比各自的结点结构可以看出,以二叉链表作为媒介可以导出树和二叉树之间的一个对应关系. ◆ 从物理结构来看,树和二叉树的二叉链表是相同的,只是对指针的逻辑解释不同而已. ◆ 从树的二叉链表表示的定义可知,任何一棵和树对应的二叉树,其右子树一定为空. 1 树转换成二叉树 对于一般的树,可以方便地转换成一棵唯一的二叉树与之对应.将树转换成二叉树在"孩子兄弟表示法"中已给出,其详细步骤是: ⑴ 加虚线.在所有兄弟结点之间加线. ⑵ 去连线.只保留大孩子(除最左的第

浅谈AVL树,红黑树,B树,B+树原理及应用

背景:这几天在看<高性能Mysql>,在看到创建高性能的索引,书上说mysql的存储引擎InnoDB采用的索引类型是B+Tree,那么,大家有没有产生这样一个疑问,对于数据索引,为什么要使用B+Tree这种数据结构,和其它树相比,它能体现的优点在哪里? 看完这篇文章你就会了解到这些数据结构的原理以及它们各自的应用场景. 二叉查找树 简介 二叉查找树也称为有序二叉查找树,满足二叉查找树的一般性质,是指一棵空树具有如下性质: 任意节点左子树不为空,则左子树的值均小于根节点的值. 任意节点右子树不为

浅谈线段树离散化

先了解一下离散化的概念,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率. 就是他要求上限是10^9,但是可能真正用到的有用的点却只有几千或者几万而已,而如果你直接用上限来做的话,任何CPU都无法运行. 离散化在线段树方面有着很大的用途: 比如数据过大时,建立线段树无法开辟那么多单元,此时就要用到离散化了. 具体步骤如下: 1.sort(a,a+n)排序.将要用到的区间或者点集排序 2.unique(a,a+n)去重,返回最后那个完成去重的点往后一个位置,好像是地址,所以减一个

浅谈B树

1.定义: b树是为了硬盘快速读取数据而设计的一种多路查找树.目前大多数数据库及文件索引,都是采用b树来储存实现的.一颗m阶B树满足如下性质: (1)树中每个节点至多有m颗子树,至少有ceil(m/2)颗子树 (2)树根节点至少有2颗子树 (3)所有叶节点都在同一层 (4)每个节点包括的数据形式是:(N,{key1, key2....keyN},{P0, P1, P2....PN},{Val1,Val2....ValN})其中,N表示关键词key的个数,P表示指向节点子树的指针,Val表示每个k

浅谈线段树 (例题:[USACO08FEB]酒店Hotel)By cellur925

今天我们说说线段树. 我个人还是非常欣赏这种数据结构的.(逃)因为它足够优美,有递归结构,有左子树和右子树,还有二分的思想. emm这个文章打算自用,就不写那些基本的操作了... 1° 简单的懒标记(仅含加法) 当我们进行区间修改(比如同时加上一个数)时,我们现在也许暂时不用它,可以当需要用的时候再改.这个时候我们就需要做个标记,这个标记就是懒标记,$lazy$.如果在后续的指令中需要从p向下递归,我们这时候检查它是否有标记.若有,就按照标记更新两个子节点,同时为子节点增加标记,清除p的标记.

可持久化专题(一)——浅谈主席树:可持久化线段树

前言 不得不说,可持久化数据结构真是太难了! 由于数据结构这东西真的太玄学了,学这个主席树我真的学了很久. 简介 主席树为什么叫主席树?据说因为它是一个名字缩写为\(HJT\)的神犇发明的,与当时主席的名字缩写一样...... 主席树实质上就是一棵可持久化线段树,它的具体实现可以看下面. 让我们从值域线段树开始说起 要学主席树,我们就要先学值域线段树. 值域线段树的区间存的并不是节点信息,而是在值在某一范围内的数的个数. 如图就是一棵值域线段树,其中1号节点存储的是大于等于1小于等于4的数字个数