数据结构之Trie树

简介: 1、什么是Trie树   Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。
1、什么是Trie树  

  Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。

    Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
它有3个基本性质:
    1.根节点不包含字符,除根节点外每一个节点都只包含一个字符。
    2.
从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
    3.
每个节点的所有子节点包含的字符都不相同。

2、Trie树的构建
     本质上,Trie是一颗存储多个字符串的树。相邻节点间的边代表一个字符,这样树的每条分支代表一则子串,而树的叶节点则代表完整的字符串。和普通树不同的地方是,相同的字符串前缀共享同一条分支。举一个例子。给出一组单词,inn, int, at, age, adv, ant, 我们可以得到下面的Trie:

搭建Trie的基本算法很简单,无非是逐一把每则单词的每个字母插入Trie。插入前先看前缀是否存在。如果存在,就共享,否则创建对应的节点和边。比如要插入单词add,就有下面几步:
    1.
考察前缀"a",发现边a已经存在。于是顺着边a走到节点a。
    2.
考察剩下的字符串"dd"的前缀"d",发现从节点a出发,已经有边d存在。于是顺着边d走到节点ad
    3.
考察最后一个字符"d",这下从节点ad出发没有边d了,于是创建节点ad的子节点add,并把边ad->add标记为d。

具体Trie树的创建、插入、查询代码如下所示:

  1. //此函数只考虑26个英文字母的情况
  2. #include<iostream>
  3. #include<cstring>
  4. using namespace std;
  5. #define MAX_CHILD 26
  6. typedef struct Tree
  7. {
  8.     int count;         //用来标记该节点是个可以形成一个单词,如果count!=0,则从根节点到该节点的路径可以形成一个单词
  9.     struct Tree *child[MAX_CHILD];
  10. }Node,*Trie_node;

  11. Node* CreateTrie()                             //创建trie节点树
  12. {
  13.     Node *node=(Node*)malloc(sizeof(Node));
  14.     memset(node,0,sizeof(Node));
  15.     return node;
  16. }

  17. void insert_node(Trie_node root,char *str)      //trie树插入结点
  18. {
  19.     if(root ==NULL || *str=='\0')
  20.         return;
  21.     Node *t=root; 

  22.     char *p=str;
  23.     
  24.     while(*p!='\0')
  25.     {
  26.      if(t->child[*p-'a']==NULL)
  27.         {
  28.          Node *tmp=CreateTrie();
  29.          t->child[*p-'a']=tmp;        
  30.         }
  31.      t=t->child[*p-'a'];
  32.      p++;
  33.     }
  34.     t->count++;
  35. }

  36. void search_str(Trie_node root,char *str)             //查找串是否在该trie树中
  37. {
  38.     if(NULL==root || *str=='\0')
  39.     {
  40.      printf("trie is empty or str is null\n");
  41.      return;
  42.     }

  43.     char *p=str;
  44.     Node *t=root;
  45.     while(*p!='\0')
  46.     {     
  47.      if(t->child[*p-'a']!=NULL)
  48.         {
  49.          t=t->child[*p-'a'];
  50.             p++;
  51.         }
  52.      else
  53.              break;
  54.     }
  55.     if(*p=='\0')
  56.     {
  57.      if(t->count==0)
  58.             cout<<"该字符串不在trie树中,但该串是某个单词的前缀\n";
  59.         else
  60.             cout<<"该字符串在该trie树中\n";
  61.     }
  62.     else
  63.         cout<<"该字符串不在trie树中\n";
  64. }

  65. void del(Trie_node root)      //释放整个字典树占的堆空间
  66. {
  67.     int i;
  68.     for(i=0;i<MAX_CHILD;i++)
  69.     {
  70.      if(root->child[i]!=NULL)
  71.             del(root->child[i]);
  72.     }
  73.     free(root);
  74. }

  75. int main()
  76. {
  77.     int i,n;
  78.     char str[20];
  79.     cout<<"请输入要创建的trie树的大小:";
  80.     cin>>n; 
  81.     Trie_node root=NULL;
  82.     root=CreateTrie(); 
  83.     if(root==NULL)
  84.         cout<<"创建trie树失败";
  85.     for(i=0;i<n;i++) 
  86.     {
  87.         scanf("%s",str);
  88.         insert_node(root,str);
  89.     }
  90.     cout<<"trie树已建立完成\n";
  91.     cout<<"请输入要查询的字符串:";
  92.     while(scanf("%s",str)!=NULL)
  93.     {
  94.      search_str(root,str);
  95.     
  96.     }
  97.     return 0;
  98. }

相关文章
|
2月前
|
算法
数据结构之博弈树搜索(深度优先搜索)
本文介绍了使用深度优先搜索(DFS)算法在二叉树中执行遍历及构建链表的过程。首先定义了二叉树节点`TreeNode`和链表节点`ListNode`的结构体。通过递归函数`dfs`实现了二叉树的深度优先遍历,按预序(根、左、右)输出节点值。接着,通过`buildLinkedList`函数根据DFS遍历的顺序构建了一个单链表,展示了如何将树结构转换为线性结构。最后,讨论了此算法的优点,如实现简单和内存效率高,同时也指出了潜在的内存管理问题,并分析了算法的时间复杂度。
67 0
|
15天前
|
存储 C++
【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
【数据结构——树】哈夫曼树(头歌实践教学平台习题)【合集】目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果:任务描述 本关任务:编写一个程序构建哈夫曼树和生成哈夫曼编码。 相关知识 为了完成本关任务,你需要掌握: 1.如何构建哈夫曼树, 2.如何生成哈夫曼编码。 测试说明 平台会对你编写的代码进行测试: 测试输入: 1192677541518462450242195190181174157138124123 (用户分别输入所列单词的频度) 预
52 14
【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
|
15天前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
38 12
|
15天前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
38 10
|
15天前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
39 2
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
90 5
|
2月前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
129 16
|
2月前
|
算法
数据结构之文件系统模拟(树数据结构)
本文介绍了文件系统模拟及其核心概念,包括树状数据结构、节点结构、文件系统类和相关操作。通过构建虚拟环境,模拟文件的创建、删除、移动、搜索等操作,展示了文件系统的基本功能和性能。代码示例演示了这些操作的具体实现,包括文件和目录的创建、移动和删除。文章还讨论了该算法的优势和局限性,如灵活性高但节点移除效率低等问题。
80 0
|
3月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
40 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
3月前
|
Java C++
【数据结构】探索红黑树的奥秘:自平衡原理图解及与二叉查找树的比较
本文深入解析红黑树的自平衡原理,介绍其五大原则,并通过图解和代码示例展示其内部机制。同时,对比红黑树与二叉查找树的性能差异,帮助读者更好地理解这两种数据结构的特点和应用场景。
53 0

热门文章

最新文章