树-trie树

字典树(trie树)

(图f)

  字典树是一种以树形结构保存大量字符串。以便于字符串的统计和查找,经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。具有以下特点(图f):
(1)根节点为空;
(2)除根节点外,每个节点包含一个字符;
(3)从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
(4)每个字符串在建立字典树的过程中都要加上一个区分的结束符,避免某个短字符串正好是某个长字符串的前缀而淹没。

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

Trie 的强大之处就在于它的时间复杂度。它的插入和查询时间复杂度都为 O(k) ,其中 k 为 key 的长度,与 Trie 中保存了多少个元素无关。Trie 的缺点是空间消耗很高。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。

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

Trie树有一些特性:
1)根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2)从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
3)每个节点的所有子节点包含的字符都不相同。
4)如果字符的种数为n,则每个结点的出度为n,这也是空间换时间的体现,浪费了很多的空间。
5)插入查找的复杂度为O(n),n为字符串长度。

下面主要介绍trie树在C++版和java版中的初始化,插入,和查询工作

定义trie树的结构体:C++版

typedef struct Trie_node  

{  int count;                    // 统计单词前缀出现的次数  

    struct Trie_node* next[26];   // 指向各个子树的指针  

    bool exist;                   // 标记该结点处是否构成单词    

}TrieNode , *Trie;  

  1. using namespace std;
  2. typedef struct Trie_node
  3. {
  4. int count;                    // 统计单词前缀出现的次数
  5. struct Trie_node* next[26];   // 指向各个子树的指针
  6. bool exist;                   // 标记该结点处是否构成单词
  7. }TrieNode , *Trie;
  8. TrieNode* createTrieNode()
  9. {
  10. TrieNode* node = (TrieNode *)malloc(sizeof(TrieNode));
  11. node->count = 0;
  12. node->exist = false;
  13. memset(node->next , 0 , sizeof(node->next));    // 初始化为空指针
  14. return node;
  15. }
  16. void Trie_insert(Trie root, char* word)
  17. {
  18. Trie node = root;
  19. char *p = word;
  20. int id;
  21. while( *p )
  22. {
  23. id = *p - ‘a‘;
  24. if(node->next[id] == NULL)
  25. {
  26. node->next[id] = createTrieNode();
  27. }
  28. node = node->next[id];  // 每插入一步,相当于有一个新串经过,指针向下移动
  29. ++p;
  30. node->count += 1;      // 这行代码用于统计每个单词前缀出现的次数(也包括统计每个单词出现的次数)
  31. }
  32. node->exist = true;        // 单词结束的地方标记此处可以构成一个单词
  33. }
  34. int Trie_search(Trie root, char* word)
  35. {
  36. Trie node = root;
  37. char *p = word;
  38. int id;
  39. while( *p )
  40. {
  41. id = *p - ‘a‘;
  42. node = node->next[id];
  43. ++p;
  44. if(node == NULL)
  45. return 0;
  46. }
  47. return node->count;
  48. }
  49. int main(void)
  50. {
  51. Trie root = createTrieNode();     // 初始化字典树的根节点
  52. char str[12] ;
  53. bool flag = false;
  54. while(gets(str))
  55. {
  56. if(flag)
  57. printf("%d\n",Trie_search(root , str));
  58. else
  59. {
  60. if(strlen(str) != 0)
  61. {
  62. Trie_insert(root , str);
  63. }
  64. else
  65. flag = true;
  66. }
  67. }
  68. return 0;
  69. }

 java版trie树初始化,插入,和查询给出的字符串为前缀的单词的个数。

import java.util.Scanner;

public class Mein {

/**
* @param args
*/
private int num;//以该节点为根的子树的个数,即以该节点所指字符串作为前缀的单词的个数
private Mein[] next;//孩子结点,若存储的是英文26个字母,则每个节点有26个孩子结点
private boolean exist;//若exist为true,则该节点所表示的字符串为一个单词,否则不是单词,如box,若节点存储o,则表示的是“bo”,不是一个单词,此时exist=false;若节点存储x,则表示的是“box”,是一个单词,此时exist=true

public static Mein init()//初始化
{
Mein node=new Mein();
node.num=0;
node.next=new Mein[26];
node.exist=false;
return node;
}
public static void insert(Mein root,String a)//插入
{
Mein nodeRoot=root;
int id;
for(int i=0;i<a.length();i++)
{
id=a.charAt(i)-‘a‘;
if(nodeRoot.next[id]==null)
{
nodeRoot.next[id]=init();
}
nodeRoot=nodeRoot.next[id];
nodeRoot.num++;
}
nodeRoot.exist=true;
}
public static int inquery(Mein root,String pre)//查询给出的字符串为前缀的单词的个数
{
Mein NodeTemp=root;
int k;
for(int i=0;i<pre.length();i++)
{
k=pre.charAt(i)-‘a‘;
if(NodeTemp.next[k]==null)
{
return 0;
}
NodeTemp=NodeTemp.next[k];
}
return NodeTemp.num;
}

public static void main(String[] args) {
// TODO Auto-generated method stub
Mein Node=new Mein();
Node=init();
Scanner s=new Scanner(System.in);
int n=s.nextInt();//输入n个字符串建立trie树
String[] dir=new String[n];
for(int i=0;i<n;i++)
{
dir[i]=s.next();
}
int m=s.nextInt();//输入m个字符串作为给定的字符串,用来查询以该字符串为前缀的单词的个数
String[] prefix=new String[m];
for(int i=0;i<m;i++)
{
prefix[i]=s.next();
}
for(int i=0;i<n;i++)
{
insert(Node,dir[i]);//向trie树插入输入的n个字符串
}
int num;
for(int i=0;i<m;i++)
{
num=inquery(Node,prefix[i]);//查询以该字符串为前缀的单词的个数
System.out.println(num);
}

}

}

时间: 2024-11-06 21:09:37

树-trie树的相关文章

[POJ] #1003# 487-3279 : 桶排序/字典树(Trie树)/快速排序

一. 题目 487-3279 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 274040   Accepted: 48891 Description Businesses like to have memorable telephone numbers. One way to make a telephone number memorable is to have it spell a memorable word or

Atitit 常见的树形结构 红黑树 &#160;二叉树 &#160;&#160;B树 B+树 &#160;Trie树&#160;attilax理解与总结

Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树2 1.4. 满二叉树和完全二叉树..完全二叉树说明深度达到完全了.2 1.5. 属的逻辑表示 树形比奥死,括号表示,文氏图,凹镜法表示3 1.6. 二叉树是数据结构中一种重要的数据结构,也是树表家族最为基础的结构.3 1.6.1. 3.2 平衡二叉

字典树Trie树

一.字典树 字典树--Trie树,又称为前缀树(Prefix Tree).单词查找树或键树,是一种多叉树结构. 上图是一棵Trie树,表示了关键字集合{"a", "to", "tea", "ted", "ten", "i", "in", "inn"} .从上图可以归纳出Trie树的基本性质: 1. 根节点不包含字符,除根节点外的每一个子节点都包含一

[转载]字典树(trie树)、后缀树

(1)字典树(Trie树) Trie是个简单但实用的数据结构,通常用于实现字典查询.我们做即时响应用户输入的AJAX搜索框时,就是Trie开始.本质上,Trie是一颗存储多个字符串的树.相邻节点间的边代表一个字符,这样树的每条分支代表一则子串,而树的叶节点则代表完整的字符串.和普通树不同的地方是,相同的字符串前缀共享同一条分支.还是例子最清楚.给出一组单词,inn, int, at, age, adv, ant, 我们可以得到下面的Trie: 可以看出: 每条边对应一个字母. 每个节点对应一项前

【BZOJ3217】ALOEXT 替罪羊树+Trie树

[BZOJ3217]ALOEXT Description taorunz平时最喜欢的东西就是可移动存储器了……只要看到别人的可移动存储器,他总是用尽一切办法把它里面的东西弄到手. 突然有一天,taorunz来到了一个密室,里面放着一排可移动存储器,存储器里有非常珍贵的OI资料……不过比较特殊的是,每个存储器上都写着一个非负整数.taorunz很高兴,要把所有的存储器都拿走(taorunz的智商高达500,他一旦弄走了这里的所有存储器,在不久到来的AHOI和NOI中……你懂的).不过这时有一个声音

【数据结构】字典树/Trie树/前缀树 - 字符串的统计、排序和保存

字典树 描述 字典树,又称单词查找树.Trie树.前缀树,是一种树形结构,是一种哈希树的变种. 典型应用是用于统计.排序和保存大量的字符串(但不仅限于字符串). 常见操作有插入和查找,删除操作少见. 性质 根节点不包含字符 除根节点外每一个节点都只包含一个字符 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串 每个节点的所有子节点包含的字符都不相同 优点 利用字符串的公共前缀来减少查询时间 最大限度地减少无谓的字符串比较 查询效率比哈希树高 自带字典序排序 直接判断重复,或者记

HiHo1014 : Trie树(Trie树模板题)

描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能对于每一个我给出的字符串,都在这个词典里面找到以这个字符串开头的所有单词呢?” 身经百战的小Ho答道:“怎么会不能呢!你每给我一个字符串,我就依次遍历词典里的所有单词,检查你给我的字符串是不是这个单词的前缀不就是了?” 小Hi笑道:“你啊,还是太年轻了!~假设这本词典里有10万个单

剑指Offer——Trie树(字典树)

剑指Offer--Trie树(字典树) Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高. Trie的核心思想是空间换时间.利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的. Trie树也有它的缺点,Trie树的内存消耗非常大.当然,或许用左儿子右兄弟的方法建树的话,可能会好点.可见,优

【转】B树、B-树、B+树、B*树、红黑树、 二叉排序树、trie树Double Array 字典查找树简介

B  树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中:否则,如果查询关键字比结点关键字小,就进入左儿子:如果比结点关键字大,就进入右儿子:如果左儿子或右儿子的指针为空,则报告找不到相应的关键字: 如果B树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么B树的搜索性