Trie树(Prefix Tree)介绍

article/2025/10/23 13:20:58

本文用尽量简洁的语言介绍一种树形数据结构 —— Trie树。

一、什么是Trie树

Trie树,又叫字典树前缀树(Prefix Tree)单词查找树键树,是一种多叉树结构。如下图:



上图是一棵Trie树,表示了关键字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”} 。从上图可以归纳出Trie树的基本性质:

  1. 根节点不包含字符,除根节点外的每一个子节点都包含一个字符。
  2. 从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。
  3. 每个节点的所有子节点包含的字符互不相同。

通常在实现的时候,会在节点结构中设置一个标志,用来标记该结点处是否构成一个单词(关键字)。

可以看出,Trie树的关键字一般都是字符串,而且Trie树把每个关键字保存在一条路径上,而不是一个结点中。另外,两个有公共前缀的关键字,在Trie树中前缀部分的路径相同,所以Trie树又叫做前缀树(Prefix Tree)


二、Trie树的优缺点

Trie树的核心思想是空间换时间,利用字符串的公共前缀来减少无谓的字符串比较以达到提高查询效率的目的。

优点

  1. 插入和查询的效率很高,都为 O(m) ,其中 m 是待插入/查询的字符串的长度。

    • 关于查询,会有人说 hash 表时间复杂度是O(1)不是更快?但是,哈希搜索的效率通常取决于 hash 函数的好坏,若一个坏的 hash 函数导致很多的冲突,效率并不一定比Trie树高。

    • Trie树中不同的关键字不会产生冲突。

    • Trie树只有在允许一个关键字关联多个值的情况下才有类似hash碰撞发生。

    • Trie树不用求 hash 值,对短字符串有更快的速度。通常,求hash值也是需要遍历字符串的。

    • Trie树可以对关键字按字典序排序。

缺点

  1. 当 hash 函数很好时,Trie树的查找效率会低于哈希搜索。

  2. 空间消耗比较大。


三、Trie树的应用

1、字符串检索

检索/查询功能是Trie树最原始的功能。思路就是从根节点开始一个一个字符进行比较:

  • 如果沿路比较,发现不同的字符,则表示该字符串在集合中不存在。
  • 如果所有的字符全部比较完并且全部相同,还需判断最后一个节点的标志位(标记该节点是否代表一个关键字)。
struct trie_node
{bool isKey;   // 标记该节点是否代表一个关键字trie_node *children[26]; // 各个子节点 
};

2、词频统计

Trie树常被搜索引擎系统用于文本词频统计 。

struct trie_node
{int count;   // 记录该节点代表的单词的个数trie_node *children[26]; // 各个子节点 
};

思路:为了实现词频统计,我们修改了节点结构,用一个整型变量count来计数。对每一个关键字执行插入操作,若已存在,计数加1,若不存在,插入后count置1。

注意:第一、第二种应用也都可以用 hash table 来做。

3、字符串排序

Trie树可以对大量字符串按字典序进行排序,思路也很简单:遍历一次所有关键字,将它们全部插入trie树,树的每个结点的所有儿子很显然地按照字母表排序,然后先序遍历输出Trie树中所有关键字即可。

4、前缀匹配

例如:找出一个字符串集合中所有以ab开头的字符串。我们只需要用所有字符串构造一个trie树,然后输出以a->b->开头的路径上的关键字即可。

trie树前缀匹配常用于搜索提示。如当输入一个网址,可以自动搜索出可能的选择。当没有完全匹配的搜索结果,可以返回前缀最相似的可能。

5、作为其他数据结构和算法的辅助结构

如后缀树,AC自动机等。


四、Trie树的实现

这里为了方便,我们假设所有的关键字都由 a-z 的字母组成。下面是 trie 树的一种典型实现:

#include <iostream>
#include <string>
using namespace std;#define ALPHABET_SIZE 26typedef struct trie_node
{int count;   // 记录该节点代表的单词的个数trie_node *children[ALPHABET_SIZE]; // 各个子节点 
}*trie;trie_node* create_trie_node()
{trie_node* pNode = new trie_node();pNode->count = 0;for(int i=0; i<ALPHABET_SIZE; ++i)pNode->children[i] = NULL;return pNode;
}void trie_insert(trie root, char* key)
{trie_node* node = root;char* p = key;while(*p){if(node->children[*p-'a'] == NULL){node->children[*p-'a'] = create_trie_node();}node = node->children[*p-'a'];++p;}node->count += 1;
}/*** 查询:不存在返回0,存在返回出现的次数*/ 
int trie_search(trie root, char* key)
{trie_node* node = root;char* p = key;while(*p && node!=NULL){node = node->children[*p-'a'];++p;}if(node == NULL)return 0;elsereturn node->count;
}int main()
{// 关键字集合char keys[][8] = {"the", "a", "there", "answer", "any", "by", "bye", "their"};trie root = create_trie_node();// 创建trie树for(int i = 0; i < 8; i++)trie_insert(root, keys[i]);// 检索字符串char s[][32] = {"Present in trie", "Not present in trie"};printf("%s --- %s\n", "the", trie_search(root, "the")>0?s[0]:s[1]);printf("%s --- %s\n", "these", trie_search(root, "these")>0?s[0]:s[1]);printf("%s --- %s\n", "their", trie_search(root, "their")>0?s[0]:s[1]);printf("%s --- %s\n", "thaw", trie_search(root, "thaw")>0?s[0]:s[1]);return 0;
}

对于Trie树,我们一般只实现插入和搜索操作。这段代码可以用来检索单词和统计词频。







个人站点:http://songlee24.github.com


http://chatgpt.dhexx.cn/article/u6lOYDVx.shtml

相关文章

configure --prefix=/的作用和用法

非root用户安装python和gcc的时候&#xff0c;总是需要设定这个&#xff0c;只知道是个路径&#xff0c;具体是什么路径&#xff0c;代表什么不清楚。 不明白就百度&#xff1a; configure --prefix/是干啥用的&#xff1f;这个路径代表了什么&#xff1f; Configure是一个可…

前缀和(Prefix Sum)

前缀和指一个数组的某下标之前的所有数组元素的和&#xff08;包含其自身&#xff09;。前缀和分为一维前缀和&#xff0c;以及二维前缀和。前缀和是一种重要的预处理&#xff0c;能够降低算法的时间复杂度&#xff0c;可以在 O ( 1 ) O(1) O(1)的时间复杂度内求出区间和。 一…

CMAKE_INSTALL_PREFIX

一、定义 CMAKE_INSTALL_PREFIX为cmake的内置变量&#xff0c;用于指定cmake执行install命令时&#xff0c;安装的路径前缀。Linux下的默认路径是/usr/local &#xff0c;Windows下默认路径是 C:/Program Files/${PROJECT_NAME} 二、用…

IP-Prefix List

地址前缀列表 一、IP-Prefix List二、语法及匹配规则1、语法2、匹配规则 三、配置案例1、拓扑2、分析ACL实现IP-Prefix List实现 四、IE考试题思考题 在进行配置案例前先了解一下基础知识 一、IP-Prefix List IP-Prefix List&#xff1a;能够同时匹配网络号和前缀长度 性能及可…

【脚本】更新依赖库pkgconfig文件中的prefix设置

在本地编译和安装了某个库后&#xff0c;如果其lib目录下存在pkgconfig子目录&#xff0c;则子目录下会存在若干.pc文件&#xff0c;文件中会有prefix的配置&#xff08;该配置标识当前库的安装路径&#xff09;&#xff0c;当要把该库拷贝到其他机器上时&#xff0c;如果库的路…

Elasticsearch学习--查询(prefix、wildcard、regexp、fuzzy)

一、前缀搜索 prefix 不计算相关度评分性能较差前缀搜索匹配的是分词后的词项前缀搜索没有缓存前缀搜索尽可能把前缀长度设置的更长 GET product/_search {"query": {"fuzzy": {"name": {"value": "product1"}}} } index…

bgp 使用route-map设置Local perference(本地优先属性)配置与详解

实验目的&#xff1a; 1、掌握基于route-map的本地优先配置方法。 2、使用route-map配置可以定置基于目标网络的本地优先。 实验拓扑&#xff1a; 接口IP配置及bgp基础配置详见 CSDNhttps://mp.csdn.net/mp_blog/creation/editor?spm1001.2014.3001.5352 查看R3与R4的路由…

使用route-map 配置BGP本地优先级

一、实验目的&#xff1a; 1、掌握基于route-map的本地优先配置方法。 2、使用route-map配置可以定置基于目标网络的本地优先级。 二、拓扑图&#xff1a; 三、配置BGP基本的配置&#xff1a; 1、配置各路由器的IP地址和BGP协议。配置完之后&#xff0c;查看一下R3和R4的路由表…

Cisco route-map 源地址路由配置

拓朴图&#xff1a; 案例&#xff1a; 公司内部使用的是一条拨号光纤和一条固定专线光纤&#xff0c;默认是指向拨号光纤出口那个网关出去&#xff0c;现在2网段有两台服务器&#xff08;WEB、Mail&#xff09;映射到公网&#xff0c;让外部来访问。 办公区因工作需要&#xf…

bgp route-map应用 配置 学习笔记

先全运行bgp R2 router bgp 2 no auto-summary no synchronzation bgp router-id 2.2.2.2 neighbor 12.1.1.1 remtotes as 10 neighbor 24.1.1.4 remote-as 10r1&#xff1a; router bgp 10 no auto-summary no synchronization bgp router-id 1.1.1.1 neighbor 12.1.1.2…

重分布和Route-MAP

一般在做重分布的时候用route-map较多&#xff0c;当然也可以用分发列表或者前缀列表等等&#xff0c;重分布的时候为了干掉不需要的路由&#xff0c;节约路由器CPU和转发效率可以使用route-map&#xff0c;当然route-map也可以用在其他的场景。 本次实验将ospf与rip重分布来使…

使用Route-Map过滤BGP的路由

实验目的 1、掌握使用Route-Map过滤BGP的路由。 实验拓扑 接口ip配置与bgp基础配置详见&#xff1a; CSDNhttps://mp.csdn.net/mp_blog/creation/editor/125210020查看R3的路由表&#xff1a; R3#show ip route Gateway of last resort is not set1.0.0.0/24 is subnetted…

基于Route-map的路由过滤配置详解

实验目的&#xff1a; 1、掌握基于Route-map的路由过滤配置方法。 2、掌握route-map的命令语法。 实验拓扑&#xff1a; 步骤1:接口ip配置路由协议基础配置重分发详见CSDNhttps://mp.csdn.net/mp_blog/creation/editor/125018583查看R1、R3路由表 R1#show ip route Gateway …

带你轻轻松松了解route-map

一、Route-map概述 1.技术背景 首先来初步认识一下route-map。看上图&#xff0c;我们在R2上&#xff0c;将OSPF路由重发布进RIP&#xff0c;前面已经说过了&#xff0c;在重发布时&#xff0c;可以使用metric关键字来设置路由被重发布进RIP后的metric&#xff0c;这里设置为…

Route-Map个人理解及实验解析

Route-Map:功能性非常强的策略列表&#xff0c;可以用来过滤路由也可以调整路由的属性&#xff0c;自身具备过滤功能。 Route-Map的作用: 1.在重发布的过程中做route-map&#xff0c;重发布过程中可以改变路由的属性&#xff1b;&#xff08;次要作用&#xff09; 2.PBR 策略路…

Route map应用策略路由(上)

一、拓扑图&#xff1a; 二、配置说明&#xff1a; 1、根据拓扑图的配置&#xff0c;R4上面跑OSPF&#xff0c;下面走静态路由&#xff0c;R5和R6走默认路由上去。但是要注意的一点是R4上要加一条命令&#xff1a;default-information originate always (向OSPF区域通知一条默认…

CISCO ROUTE-MAP

强制指定源地址的下一跳 match定义匹配条件 match ip address匹配访问列表或前缀列表 match interface匹配下一跳出接口为指定接口之一的路由 match ip next-hop匹配下一跳地址为特定访问列表中被允许的那些路由 match metric匹配具有指定度量值的路由 match route-type匹…

Route-map扩展(讲解+配置)

目录 ——Route-map扩展一般形式&#xff1a; ——案列&#xff08;1&#xff09;&#xff1a; ——案列&#xff08;2&#xff09;&#xff1a; ——Route-map扩展一般形式&#xff1a; Ip policy-list aaa per/denyMatch …………&#xff08;前缀列表/ACL....&#xff…

路由策略route-map

路由策略 route-map 定义 route-map&#xff0c;路由图&#xff0c;用于实现路由策略。 功能 部署 route-map NM permit 10 match ip address 1 2 match ip address 1 match ip address 2 match interface f0/0 f1/0 route-map NM deny 20 match ip address 2 set weight …