在计算机科学中,trie,又称前缀树字典树,是一种有种树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。

  本质上,Trie是存储多个字符串的树。

  Trie树的思想是利用字符串的公共前缀降低时空开销

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

  Trie树最大的优点是最大限度减少无谓的字符串比较。

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

以下几个博客的讲解很详细:

1. http://blog.csdn.net/hackbuteer1/article/details/7964147

2. http://blog.csdn.net/v_july_v/article/details/6897097

3. http://blog.csdn.net/luxiaoxun/article/details/7937589

4. 《王道程序员求职宝典》 P276

5. geeksforgeeks trie树讲解。

使用范围:

  1. 词频统计 2.前缀匹配 3.全词匹配

 #include<iostream>
#include<string>
using namespace std; class Trie{
public:
Trie();
~Trie();
void Insert(const string &s);
bool Search(const string &s) const;
private:
struct TrieNode{
int count; //单词出现的次数
TrieNode *next[];
TrieNode(): count(), exist(false) {
memset(next, NULL, sizeof(next));
}
}; TrieNode *root_; void MakeEmpty(TrieNode *root);
}; Trie::Trie() {
root_ = new TrieNode();
} Trie::~Trie() {
MakeEmpty(root_);
} void Trie::Insert(const string &s) {
int len = s.size();
TrieNode *position = root_;
for (int i =; i < len; ++i) { //不存在建立一个节点
if (position->next[s[i] - 'a'] == NULL) {
position->next[s[i] -'a'] = new TrieNode();
}
position = position->next[s[i] - 'a']; //每插入一步,相当于一个新串经过,指针要向下移动
} position->count++; } bool Trie::Search(const string &s) const {
if (root_ == NULL) return false; int len = s.size();
TrieNode *location = root_;
for (int i = ; i < len && location != NULL; ++i) {
if (location->next[s[i] - 'a'] == NULL) {
return false;
}
location = location->next[s[i] - 'a'];
} return p != NULL && location->count != 0;
} void Trie::MakeEmpty(TrieNode *root) {
for (int i = ; i < ; ++i) {
if (root->next[i] != NULL)
MakeEmpty(root->next[i]);
} delete root;
root = NULL;
}

建树的时间复杂度为O(len * n),n表示单词数量,len表示单词平均长度。

Trie的空间复杂度为O(sizeof(next) * len * n).冗余度较高,更高效的存储方法是compressed trie和ternary search tree,

Trie树的应用:

    • 有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词。
    • 1000万字符串,其中有些是重复的,需要把重复的全部去掉,保留没有重复的字符串。请怎么设计和实现?
    • 一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10个词,请给出思想,给出时间复杂度分析。
    • 寻找热门查询:
    • 搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。假设目前有一千万个记录,这些查询串的重复读比较高,虽然总数是1千万,但是如果去除重复和,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就越热门。请你统计最热门的10个查询串,要求使用的内存不能超过1G。

【经典数据结构】Trie的更多相关文章

  1. 大公司面试经典数据结构与算法题C#/Java解答

    几个大公司(IBM.MicroSoft and so on)面试经典数据结构与算法题C#解答 1.链表反转 我想到了两种比较简单的方法 第一种是需要开一个新的链表,将原链表的元素从后到前的插入到新链表 ...

  2. 为什么hash作为内存使用的经典数据结构?

    听到这样说法:hash是内存中使用的经典数据结构.内存是典型的随机访问设备. 为什么hash这种数据结构很适合内存使用呢?如何理解内存是随机访问设备呢? 因为我想知其所以然,如何理解背后的原因,我花费 ...

  3. 数据结构—— Trie (前缀树)

    实现一个 Trie (前缀树),包含 插入, 查询, 和 查询前缀这三个操作. Trie trie = new Trie(); trie.insert("apple"); trie ...

  4. Poj The xor-longest Path 经典题 Trie求n个数中任意两个异或最大值

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5646   Accepted: 1226 Description In an ...

  5. 【经典数据结构】B树与B+树

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为“在计算机科学中,B树 ...

  6. 数据结构~trie树(字典树)

    1.概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. 我理解字典树是看了这位大佬博客.还不了解字典树的 ...

  7. 【经典数据结构】B树与B+树(转)

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为“在计算机科学中,B树 ...

  8. 数据结构 -- Trie字典树

    简介 字典树:又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种. 优点:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高. 性质:   1.  根节 ...

  9. 【经典数据结构】B树与B+树的解释

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 前面讲解了平衡查找树中的2-3树以及其实现红 ...

随机推荐

  1. 实验四android开发基础

    实验四android开发基础 提交点一 Android Stuidio的安装测试: 参考<Java和Android开发学习指南(第二版)(EPUBIT,Java for Android 2nd) ...

  2. 20155210 潘滢昊 Java第三次实验

    Java第三次实验 实验内容 在IDEA中使用工具(Code->Reformate Code)把代码重新格式化 在码云上把自己的学习搭档加入自己的项目中,确认搭档的项目加入自己后,下载搭档实验二 ...

  3. 20155320信息安全系统设计第二周课堂考试总结及myod的实现

    20155320 信息安全系统设计第二周课堂考试总结及myod的实现 第二周测试一二已在课上提交 第二周测试3-gdb测试 用gcc -g编译vi输入的代码 在main函数中设置一个行断点 在main ...

  4. 20145234黄斐《网络对抗技术》PC平台逆向破解

    Shellcode注入 基础知识 Shellcode实际是一段代码,但却作为数据发送给受攻击服务器,将代码存储到对方的堆栈中,并将堆栈的返回地址利用缓冲区溢出,覆盖成为指向 shellcode的地址. ...

  5. day 13 字典dict 操作

    1.len   键值对的个数 In [4]: nums = [11,22,33] In [6]: len(nums) Out[6]: 3 In [7]: infor = {"name&quo ...

  6. Linux系统处理木马病毒的思路

    一.清除木马程序步骤 1.1 执行命令,每1秒刷新一次,显示整个命令路径,而不是命令的名称. [root@linux-node1 ~]# top -d -c 1.2 查找可疑进程(比较奇怪的进程名称) ...

  7. 搭建 ssm 环境

    <!-- 引入外部jdbc配置文件 --> <context:property-placeholder location="classpath:dbconfig.prope ...

  8. Qt-QML-Canvas写个小小的闹钟

    先看下演示效果 大致过程 先绘制仪表盘,圆圈和刻度 剩下再绘制三个指针 最后在绘制上面的电子时钟 下面写源代码 import QtQuick 2.0 Rectangle { id:root ancho ...

  9. 136.只出现一次的数字 leetcode ^运算符 JavaScript解法

    leetcode上的一道题简单题 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间 ...

  10. vps搭建个人网盘不二之选—kodexplorer介绍,包含安装步骤

    之前给大家介绍过seafile.h5ai等网盘系统,今天给大家介绍下kodexplorer网盘系统.Kodexplorer,也叫芒果云.可道云.kodcloud,总之名字改了不少.但其本身作为一个网盘 ...