Trie树及其应用

Trie树


Trie树,又称单词查找树、字典树,是一种树形结构,是一种哈希树的变种,是一种用于快速检索的多叉树结构。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。

Trie树的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。 Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。 Trie树也有它的缺点,Trie树的内存消耗非常大.

Trie树的结构特点:

1.root结点没有数据

2.除根结点外每个结点只包含一个字符

3.从根结点到某一个结点正好组成一个字符串

Trie树的大致结构如下:

Trie树的实现

下面是一个简单的Trie树的实现,假定只包括26个字符,忽略大小写。


1
 
#include <stdlib.h>

class Trie{
public:
Trie();
~Trie(); int insert(const char* str);
int search(const char* str)const;
int remove(const char* str); static const int CharNum = 26; protected:
typedef struct s_Trie_Node{
bool isExist;
struct s_Trie_Node* branch[Trie::CharNum];
s_Trie_Node();
}Trie_Node; Trie_Node* root;
}; Trie::Trie():root(NULL){}
Trie::~Trie(){} Trie::s_Trie_Node::s_Trie_Node():isExist(false){
for(int i = 0; i < Trie::CharNum; ++i){
branch[i] = NULL;
}
} int Trie::insert(const char* str){ if(root == NULL){
root = new Trie_Node();
} Trie_Node* pos = root;
int char_pos; while(pos != NULL && *str != '\0'){
if(*str >= 'a' && *str <= 'z'){
char_pos = *str - 'a';
} else if(*str >= 'A' && *str <= 'Z'){
char_pos = *str - 'A';
} else {
return -1;
} if(pos->branch[ char_pos] == NULL){
pos->branch[ char_pos ] = new Trie_Node();
} pos = pos->branch[ char_pos ]; str++;
} if(pos->isExist){
return 0;
} else {
pos->isExist = true;
return 1;
}
} int Trie::search(const char* str)const{
Trie_Node* pos = root; int char_pos;
while(pos != NULL && *str != '\0'){
if(*str >= 'a' && *str <= 'z'){
char_pos = *str - 'a';
} else if(*str >= 'A' && *str <= 'Z'){
char_pos = *str - 'A';
} else {
return -1;
} pos = pos->branch[char_pos];
str++;
} if(pos != NULL && pos->isExist){
return 1;
} else {
return 0;
}
} int Trie::remove(const char* str){
Trie_Node* pos = root; int char_pos; while(pos != NULL && *str != '\0'){
if(*str >= 'a' && *str <= 'z'){
char_pos = *str - 'a';
} else if(*str >= 'A' && *str <= 'Z'){
char_pos = *str - 'A';
} else {
return -1;
} pos = pos->branch[ char_pos ];
str++;
} if(pos != NULL && pos->isExist){
pos->isExist = false;
return 1;
} else {
return 0;
}
}
1
 

Trie树的应用


1. 大量字符串的统计,查找

用的比较多的场合,例如:搜索引擎对文本中词频的统计,搜索引擎日志对用户关键词搜索频率的统计,等等。下面讨论两道经典的面试题:

1.找出大量日志文件中,出现次数前10的网址。

这个问题使用Trie树再适合不过了,对于大量日志文件的统计,使用trie树速度相当快。结合最小堆和trie树,对日志文件搜索一次就可以得到结果。

2.实现一个网站的输入提示功能

这个问题需要在用户输入的时候,实时展示输入建议,使用trie树可以轻松实现。

2.字符串的排序

对于大规模字符串的排序,只需要统计一次字符串,构造trie树,然后遍历输出就得到排序结果。

3.找字符串的最长公共前缀

这个问题显而易见。

作者:bigwangdi 
出处:http://www.cnblogs.com/bigwangdi/ 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 
Stay Hungry, Stay Foolish!!

 

Trie树及其应用的更多相关文章

  1. 基于trie树做一个ac自动机

    基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...

  2. 基于trie树的具有联想功能的文本编辑器

    之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...

  3. hihocoder-1014 Trie树

    hihocoder 1014 : Trie树 link: https://hihocoder.com/problemset/problem/1014 题意: 实现Trie树,实现对单词的快速统计. # ...

  4. 洛谷P2412 查单词 [trie树 RMQ]

    题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个单词表,包含N个单词 ...

  5. 通过trie树实现单词自动补全

    /** * 实现单词补全功能 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #incl ...

  6. #1014 Trie树

    本题主要是求构造一棵Trie树,即词典树用于统计单词. C#代码如下: using System; using System.Collections.Generic; using System.Lin ...

  7. Trie树-字典查找

    描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题: ...

  8. Trie树的创建、插入、查询的实现

    原文:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28977986&id=3807947 1.什么是Trie树 Tr ...

  9. Trie树(c++实现)

    转:http://www.cnblogs.com/kaituorensheng/p/3602155.html http://blog.csdn.net/insistgogo/article/detai ...

  10. [转]双数组TRIE树原理

    原文名称: An Efficient Digital Search Algorithm by Using a Double-Array Structure 作者: JUN-ICHI AOE 译文: 使 ...

随机推荐

  1. linux内核源码目录(转)

    Linux用来支持各种体系结构的源代码包含大约4500个C语言程序,存放在270个左右的子目录下,总共大约包含200万行代码,大概占用58MB磁盘空间. 源代码所有在目录:/usr/src/linux ...

  2. PyCharm 使用简介

    PyCharm 使用简介 最近由于项目需要,领导要求使用python以方便扩展,没有办法,赶鸭子上架花了2天时间翻完了python的初级教程然后就开始写代码.有一款好的IDE可以帮助我快速上手一门新语 ...

  3. ASP.NET如何显示农历时间

    ASP.NET如何显示农历时间 CS部分代码如下: 代码如下: public string ChineseTimeNow = "";  public string ForignTi ...

  4. 阐述 QUEST CENTRAL FOR DB2 八罪

    作为一个从事oracle plsql发展2猿 - 年计划,现在,在退出DB2数据仓库项目. 同PL/SQL Developer参考,下文PLSQL,阐述QUEST CENTRAL FOR DB2 5. ...

  5. Asterisk 未来之路3.0_0006

    原文:Asterisk 未来之路3.0_0006 Modules Asterisk 是基于模块构建的.一个模块提供某个特定的功能,它是动态的被装载.比如:信道驱动(chan_sip.so),或可以连接 ...

  6. JavaScript的闭包特性

    闭包是一个比较抽象的概念,尤其是对js新手来说.在这里,我就我个人的理解j简单谈一下: 闭包:官方解释是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部 ...

  7. 在Win7中安装程序集到GAC

    原文:在Win7中安装程序集到GAC 微软为提高系统安全,自Vista推出后,在Windows系统中加入了一个新的东东——UAC(User Account Control),这样一个新的技术使得许多操 ...

  8. log4net项目中如何配置,以下详解

    log4net.config配置文件 <?xml version="1.0" encoding="utf-8"?> <log4net debu ...

  9. 枚举for/in

    for/in循环可以遍历对象中所有可以枚举的属性(包括自有属性和继承属性).对象继承的内置方法不能枚举,凡是在代码中给对象自己或者继承的类添加的属性方法都是可枚举的,但是对象自有的内置属性可不可以枚举 ...

  10. C++中的静态多态和动态多态

    C++中的静态多态和动态多态 今天的C++已经是个多重泛型编程语言(multiparadigm programming lauguage),一个同时支持过程形式(procedural).面向对象形式( ...