Trie字典树算法

特性

Trie树属于树形结构,查询效率比红黑树和哈希表都要快。假设有这么一种应用场景:有若干个英文单词,需要快速查找某个单词是否存在于字典中。使用Trie时先从根节点开始查找,直至匹配到给出字符串的最后一个节点。在建立字典树结构时,预先把带有相同前缀的单词合并在同一节点,直至两个单词的某一个字母不同,则再从发生差异的节点中分叉一个子节点。

节点结构:
每个节点对应一个最大可储存字符数组。假设字典只存26个小写英文字母,那么每个节点下应该有一个长度为26的数组。换言说,可存的元素类型越多,单个节点占用内存越大。如果用字典树储存汉字,那么每个节点必须为数千个常用汉字开辟一个数组作为储存空间,占用的内存实在不是一个数量级。不过Trie树就是一种用空间换时间的数据结构,鱼和熊掌往往不可兼得。

建树细节:

  • 取要插入字符串的首个字符,从根节点的孩子节点开始,匹配当前字符是否已有节点,有则把指针指向该节点。无则为该字符创建节点,并把指针指向该新建节点。
  • 迭代。
  • 遇到要插入字符串末尾结束符时停止迭代,并把最后一个非’\0′字符对应的节点设为末端节点。

查找细节:
循环取要插入字符串的首个字符,从根节点的孩子节点开始,匹配当前字符是否已有节点,有则继续循环,无则返回False. 直至匹配到最后一个字符则完成查找。

树结构图:
我们用apps, apply, apple, append, back, basic, backen几英文单词创建树形结构:

上图很容易看出,有相同前缀的英文单词,会合并在同一个节点,Trie树顺着一个个节点进行检索,直至找到最后一个节点。代码如下:

 1 #include <stdio.h>
 2
 3 struct trie_node
 4 {
 5     static const int letter_count = 26;
 6
 7     int count;
 8     bool is_terminal;
 9     char letter;
10     trie_node* childs[letter_count];
11
12     trie_node()
13         : letter(0), count(1), is_terminal(false)
14     {
15         for (int i = 0; i < letter_count; ++i)
16             childs[i] = NULL;
17     }
18 };
19
20 class trie
21 {
22 public:
23     trie()
24         : root_node_(NULL)
25     {
26     }
27
28     ~trie()
29     {
30         delete_trie(root_node_);
31     }
32
33 public:
34     trie_node* create()
35     {
36         trie_node* n = new trie_node();
37         return n;
38     }
39
40     void insert(const char* str)
41     {
42         if (!root_node_ || !str)
43             root_node_ = create();
44
45         trie_node* next_element_node = root_node_;
46         while (*str != 0)
47         {
48             char element_index = *str - ‘a‘;
49             if (!next_element_node->childs[element_index])
50             {
51                 next_element_node->childs[element_index] = create();
52             }
53             else
54             {
55                 next_element_node->childs[element_index]->count++;
56             }
57
58             next_element_node = next_element_node->childs[element_index];
59             next_element_node->letter = *str;
60             str++;
61         }
62
63         next_element_node->is_terminal = true;
64     }
65
66     bool find_word_exists(const char* str)
67     {
68         if (!root_node_ || !str)
69             return NULL;
70
71         trie_node* element_node = root_node_;
72         do
73         {
74             element_node = element_node->childs[*str - ‘a‘];
75             if (!element_node) return false;
76             str++;
77         } while (*str != 0);
78
79         return element_node->is_terminal;
80     }
81
82     void delete_trie(trie_node* node)
83     {
84         if (!node) return;
85         for(int i = 0; i < trie_node::letter_count; i++)
86         {
87             if(node->childs[i] != NULL)
88                 delete_trie(node->childs[i]);
89         }
90
91         delete node;
92     }
93
94 private:
95     trie_node* root_node_;
96 };

转:http://powman.org/archives/trie.html

Trie字典树算法,布布扣,bubuko.com

时间: 2024-11-02 23:24:35

Trie字典树算法的相关文章

go路由httprouter中的压缩字典树算法图解及c++实现

目录 go路由httprouter中的压缩字典树算法图解及c++实现 前言 httprouter简介 压缩字典树 概念 插入操作 查询操作 c+++实现 go路由httprouter中的压缩字典树算法图解及c++实现 @ 前言 准备从嵌入式往go后端转,今年准备学习一下gin框架,决定先从这个轻量级的路由请求器着手,本文讲讲它用到的压缩字典树算法. httprouter简介 HttpRouter是一个Go编写的轻量级的高性能Http请求路由器(也可称为多路选择器multiplexer简称mux)

巧用字典树算法,轻松实现日志实时聚类分析

by 田富龙日志分析对于企业运维来说尤为重要,运维人员如不能实时了解服务器的安全状况,会给企业造成难以估计的损失.对日志进行分析,不仅可以了解到软.硬件设备的运行状况,还可以了解到报错日志的源头.服务器上正在发生的安全事件,判断错误是由应用引发的还是系统本身引起的,从而及时进行补救,以提高企业软.硬件设备的高可用性.然而,随着服务器数量逐渐增加,日志数据也与日俱增,面对这种境况,利用传统的方式对日志进行分析,显然已经不能满足企业的要求.此时,基于AI技术的日志分析方式就显得尤为重要.本文提出的实

DFA和trie字典树实现敏感词过滤(python和c语言)

现在做的项目都是用python开发,需要用做关键词检查,过滤关键词,之前用c语言做过这样的事情,用字典树,蛮高效的,内存小,检查快. 到了python上,第一想法是在pip上找一个基于c语言的python字典树模块,可惜没找到合适的,如果我会用c写python模块的话,我就自己写一个了,可惜我还不具备这个能力, 只能用python写了,性能差一点就差点吧,内存多一点也无所谓了. 用搜索引擎看CSDN上的网友的用python实现的DFA,再参照自己以前用c语言写过的字典树,有些不大对,就自己写了一

Trie 字典树 删除操作

字典树的删除操作: 1 没找到直接返回 2 找到叶子节点的时候,叶子节点的count标志清零,代表不是叶子节点了 3 如果当前节点没有其他孩子节点的时候,可以删除这个节点 判断是否需是叶子节点,就检查叶子节点的count标志就可以了. 判断是否有其他孩子节点就需要循环26个节点了,如果都为空,那么就没有其他孩子节点了. #include <stdio.h> #include <stdlib.h> #include <iostream> #include <vect

Trie字典树 动态内存

Trie字典树 1 #include "stdio.h" 2 #include "iostream" 3 #include "malloc.h" 4 #include "string.h" 5 6 using namespace std; 7 8 #define MAX_SIZE 26 9 10 typedef struct Trie{ 11 char val; 12 bool isword; 13 struct Trie*

萌新笔记——C++里创建 Trie字典树(中文词典)(插入、查找、遍历、导入、导出)(上)

写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示一串可能要搜索的东西. 首先放上最终的结果: input: 1 编程入门 2 编程软件 3 编程学习 4 编程学习网站 output: 1 char : 件 2 word : 编程软件 3 char : 习 4 word : 编程学习 5 char : 网 6 word : 编程学习网 7 char : 门 8 word : 编程入门 其实这里不应

算法导论:Trie字典树

1. 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. Trie一词来自retrieve,发音为/tri:/ “tree”,也有人读为/tra?/ “try”. Trie树可以利用字符串的公共前缀来节约存储空间.如下图所示,该trie树用10个节点保存了6个字符串pool.prize.preview.prepare.produce.progress 在该trie树中,字符串preview,prepa

trie/字典树几题

以后有好多次看到这地方就过去了, 未亲自实践过. 不过今晚看了一下,感觉trie的思想还算是比较基础的. 感觉这一个链接讲的不错:http://www.cnblogs.com/BeyondAnyTime/archive/2012/07/16/2592838.html 顺便水了几道题. 具体列表可见:http://vjudge.net/contest/view.action?cid=47036#overview A:水题啦. 稍微理解下trie就能写出来了. 附个自己写的代码,还是用LRJ书上的非

【oiClass1502】查单词(Trie字典树)

题目描述 全国英语四级考试就这样如期来了,可是小y依然没有做好充分准备.为了能够大学毕业,可怜的小y决定作弊.小y费尽心机,在考试的时候夹带了一本字典进考场,但是现在的问题是,考试的时候可能有很多的单词要查,小y能不能来得及呢? 输入 第一行一个整数N,表示字典中一共有多少个单词(N<=10000).接下来每两行表示一个单词,其中:第一行是一个长度<=100的字符串,表示这个单词,全部小写字母,单词不会重复.第二行是一个整数,表示这个单词在字典中的页码.接下来是一个整数M,表示要查的单词数(M