数据结构-前缀树

  • 前缀树

    • 前缀树定义

      • 前缀树(Trie树),又称字典树、单词查找树或键树,是一种专门设计用于高效存储和检索字符串集合中词项的树形数据结构。其核心特性在于能够快速实现字符串的前缀匹配,极大减少了无谓的字符比较,从而提高了查询效率。
    • 前缀树的特性

      • 前缀编码
        • 每个节点代表一个字符串前缀,从根节点到任一节点的路径上的字符序列构成该节点对应的前缀。
        • 整棵树编码了所有存储在其中的字符串及其所有前缀。
      • 唯一路径
        • 树中不存在两条路径表示相同的前缀,保证了每个前缀在树中仅有一条对应路径,避免了重复存储。
      • 字符导向
        • 每个节点的子节点按字符集(通常是字母表)中的字符进行组织,边标签表示字符。
        • 从一个节点到其子节点的转移代表了字符串中字符的添加或延续。
      • 高效查询
        • 支持快速的字符串前缀查询:只需从根节点开始,沿着待查询前缀的字符顺序逐层向下遍历,即可判断该前缀是否存在。
        • 如果查询路径在树中完整存在,可以立即得知待查询前缀存在于词典中;否则,路径在某处中断,表明不存在。
      • 自动去重
        • 由于每个前缀对应树中唯一的路径,所以在插入过程中,重复的字符串(及其所有前缀)会被自动识别并忽略,无需额外的去重操作。
    • 构建前缀树

      1. 初始化根节点:创建一个空节点作为前缀树的根节点,通常标记为空字符或特殊值(如null、'_'等),表示没有任何字符。
      2. 遍历输入字符串集合:对于输入的每一个字符串(词项),按照以下步骤将其插入到前缀树中。
      3. 插入单个字符串:从根节点开始,逐个字符处理当前字符
        1. 检查当前节点:查看当前节点是否有与当前字符相匹配的子节点。如果有,则沿着该子节点继续处理下一个字符;如果没有,则创建一个新的子节点,将该子节点与当前字符关联,并将其父节点设置为当前节点。
        2. 递归插入:重复步骤a,处理剩余字符,直至字符串结束。
        3. 标记词结束标记:当处理完字符串的最后一个字符时,将该节点标记为词项结束节点(如设置一个布尔标志isEndOfWord为true,或在节点中记录一个计数器end等)以表示当前路径代表一个完整的词项。
      4. 处理完所有字符串:当所有输入字符串都已按照上述过程插入到前缀树中,构建过程结束,得到的树结构即为包含所有输入字符串及其前缀的前缀树。
    • 代码实现

      public class Trie {static class TrieNode{char ch;//字符boolean isEndOfWord;//是否为完整词项//子节点映射Map<Character, TrieNode> children;public TrieNode(char ch) {this.ch = ch;this.isEndOfWord=false;this.children=new HashMap<>();}}private final TrieNode root;public Trie() {this.root = new TrieNode('\0');//用'\0'代表根节点}//1.插入节点public void insert(String word){//从根节点开始插入TrieNode current=root;//遍历待查询字符串每个字符for (char ch:word.toCharArray()){/*** 这句代码 current.children.computeIfAbsent(ch, TrieNode::new) 的作用是*1.在当前节点 current 的子节点映射 children 中查找键为 ch 的条目。* 2.如果找到了,返回与 ch 关联的子节点。* 3.如果没找到,使用 TrieNode 构造函数(通过 TrieNode::new 方法引用)创建一个新的 TrieNode 实例,* 其中字符属性 ch 设置为传递给 computeIfAbsent 的 ch 参数,并将这个新创建的节点作为新值添加到映射中(键为 ch),* 然后返回这个新创建的节点。*/current=current.children.computeIfAbsent(ch,TrieNode::new);}//标记当前节点为词项的结束节点current.isEndOfWord=true;}//2.查询字符串是否存在于前缀树中public boolean search(String word){//从根节点开始TrieNode current = root;//遍历每个字符for (char ch:word.toCharArray()){//获取与当前节点对应的子节点,若不存在返回nullTrieNode node = current.children.get(ch);if (node==null){return false;}current=node;}return current.isEndOfWord;}//3.删除字符串public boolean delete(TrieNode currentNode,String word,int index){//1.若处理完所有字符串if (index==word.length()){//若不是则说明字符串不在树中,返回falseif (!currentNode.isEndOfWord){return false;}//将当前节点的词项结束标点设置为falsecurrentNode.isEndOfWord=false;//检查当前节点是否还有其他节点return currentNode.children.isEmpty();}//2.若还有字符串没有处理完//获取待删除字符串的当前节点char ch = word.charAt(index);//2.1获取当前节点的子节点,若该节点不存在,返回nullTrieNode node = currentNode.children.get(ch);if (node==null){return false;}//2.2若找到子节点,递归删除boolean shouldDeleteCurrentNode = delete(node, word, index + 1);//2.3如果递归删除子节点后返回true,说明子节点没有了其他节点,该子节点已无用可以删除if (shouldDeleteCurrentNode){currentNode.children.remove(ch);//若当前节点无其他子节点,就删除该节点return currentNode.children.isEmpty();}//2.4若此节点无需删除,返回falsereturn false;}
      }
      
    • 前缀树的时间复杂度分析

      • 时间复杂度
        • 插入:构建前缀树时,插入一个字符串的时间复杂度通常为 O(L), 其中 L 是字符串的长度。这是因为插入过程中需要遍历整个字符串,为每个字符创建或查找相应的节点。
        • 查询:查询一个字符串(或其前缀)是否存在于前缀树中的时间复杂度为 O(L),因为同样需要遍历整个字符串,沿着树结构逐个比较字符。
        • 删除:删除一个字符串的时间复杂度理论上也为 O(L),因为需要找到该字符串在树中的完整路径。
      • 空间复杂度
    • 前缀树的应用

      • 自动补全:在搜索引擎、文本编辑器、编程IDE或手机输入法中,当用户输入一部分字符时,系统能够快速列出所有可能的、以当前输入为前缀的完整词汇供用户选择。
      • 词频统计与排序:前缀树可用于统计大量文本数据中各单词出现的频率,并支持按照字母顺序输出。每个节点的计数可以表示以该节点为终点的词频,同时,由于前缀树的天然排序特性,可以按字典序遍历节点及其子节点来获取有序的单词列表。
      • 拼写检查与纠正:在文字处理软件或在线文本编辑平台中,前缀树可以帮助快速识别用户输入的单词是否存在于词库中,从而提示可能的拼写错误。
      • ip路由表查询:在计算机网络中,路由器使用前缀树(通常称为PATRICIA树或Ternary Search Tree)来存储和查找IP地址前缀,以确定数据包的下一跳转发地址。
      • 数据压缩:在某些数据压缩算法中,如LZ78,前缀树用于存储已出现过的字符串及其编码,新出现的字符串可以以其最长前缀作为索引来查找编码,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/829788.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于java的商店积分管理系统的设计与实现

功能需求 从功能上可以划分为个人信息管理、商店管理、平台管理、订单管理和数据分析。后台管理系统主要服务于商户和平台管理员&#xff0c;兑换用户是属于商户平台的自有用户&#xff0c;不会被纳入到后台管理系统中来。商户用户可以对自己的积分进行管理&#xff0c;平台管…

echarts下载图片

toolbox: {show: true,//展示工具栏itemSize:20,//icon的大小iconStyle:{borderColor:"#409eff",borderWidth:"3",color:"#fff"},right:"40px",//偏移位置feature: {saveAsImage: {title: "下载图表", //鼠标滑过之后文案na…

用wps自带工具给图片做标注

在wps中&#xff0c;选中wps中的图片&#xff0c;右键选择【编辑】进入图片编辑器&#xff0c;在选项卡面板右侧选择【标注】工具&#xff0c;再选择【添加文本】工具&#xff0c;即可直接在图片上输入文字&#xff0c;标注完成后选择【覆盖原图】就完成标注任务。

【Canvas与艺术】绘制美国星条旗

注意&#xff1a; 该图位置和大小都是按照网上说明精确绘制的。 【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>使…

FA-128晶振用于医疗设备

血糖仪已成为家庭常用的医疗设备,日本爱普生晶振公司生产的2016封装,32MHz贴片晶振可完美应用于医疗器械血糖仪,此款晶振订货型号为X1E000251005900晶振,型号为FA-128,负载电容分8PF,精度10PPM,其尺寸参数为2.0x1.6x0.5mm,符合ROHS标准且无铅,具有封装尺寸超小,高精度,频率范围…

C++ | Leetcode C++题解之第55题跳跃游戏

题目&#xff1a; 题解&#xff1a; class Solution { public:bool canJump(vector<int>& nums) {int n nums.size();int rightmost 0;for (int i 0; i < n; i) {if (i < rightmost) {rightmost max(rightmost, i nums[i]);if (rightmost > n - 1) {r…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(一)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 1 - 2节&#xff09; P1《课程介绍》 开场白&#xff0c;HarmonyOS 的一个简介&#xff0c;话不多说&#xff0c;直接看图吧&…

第十五届蓝桥杯省赛第二场C/C++B组C题【传送阵】题解(AC)

解题思路 由于 a a a 数组是一个 1 1 1 到 n n n 的一个排列&#xff0c;那么形成的一定是如下形式&#xff1a; 一定会构成几个点的循环&#xff0c;或者是几个单独的点。 从任意点开始&#xff0c;如果能进入一个循环&#xff0c;一定可以将整个循环的宝藏都拿走&#x…

[vant] 图片预览关闭按钮显示不正常

如果这里显示不正常, 那就应该是按照文档引入了 显示有问题, 直接不引入, 声明一下就行

每日论文推荐:我们距离GPT-4V有多远,最接近GPT-4V的开源多模态大模型

&#x1f4cc; 元数据概览&#xff1a; 标题&#xff1a;How Far Are We to GPT-4V? Closing the Gap to Commercial Multimodal Models with Open-Source Suites作者&#xff1a;Zhe Chen, Weiyun Wang, Hao Tian, Shenglong Ye, Zhangwei Gao, Erfei Cui, Wenwen Tong, Kon…

企业计算机服务器中了helper勒索病毒怎么办?Helper勒索病毒解密处理流程

网络技术的不断发展与成熟&#xff0c;为企业的生产运营提供了极大便利&#xff0c;让企业的发展速度大大提升&#xff0c;但网络毕竟是虚拟服务系统&#xff0c;虽然可以为企业提供便利&#xff0c;但也会给企业数据安全带来严重威胁。近日&#xff0c;云天数据恢复中心接到山…

c++中的链表list的模拟实现

拖更了半个月&#xff0c;我终于来填c的坑啦。上次我们说的vetcor不知道小伙伴还记得多少呢&#xff1f;今天我们要讲list的模拟实现。 目录 架构结点list表的结构 构造函数尾插push_back()尾删pop_back()计算个数&#xff1a;size()判断空empty()※迭代器问题普通迭代器迭代器…

CSS高级选择器

一、属性选择器 以value开头的att属性的E元素&#xff1a;E[att^"value"]{ ;} a[href^http]{background-color"red";} css a[href^http]{background-color"red"; } html <!DOCTYPE html> <html lang"en"> <head&…

《QT实用小工具·四十四》支持图片和动图的文本编辑器

1、概述 源码放在文章末尾 该项目实现了一个功能丰富的文本编辑器&#xff0c;除了包含文本常规的编辑功能&#xff0c;还包括图片的插入功能和动图的插入功能&#xff0c;项目demo演示如下所示&#xff1a; 项目部分代码如下所示&#xff1a; #include "imagehelper.…

echarts实现水滴图

使用echarts实现水滴图 引入依赖&#xff0c;echarts-liquidfill3兼容echarts5; 安装依赖 "echarts": "^5.4.3","echarts-liquidfill": "^3.1.0",npm install echarts-liquidfill3.1.0 -S实现的效果图 构建一个水滴图的页面 <tem…

Scanpy(1)数据结构和样本过滤

注&#xff1a;主要讲述scanpy处理数据的结构、数据过滤&#xff08;生信领域&#xff09;和数据预处理&#xff08;和机器学习类似&#xff0c;但是又有不同。&#xff09; 1. Scanpy简介与安装 Scanpy 是一个可扩展的工具包&#xff0c;用于分析与 AnnData&#xff08;一种…

SpringCloud系列(19)--将服务消费者Consumer注册进Consul

前言&#xff1a;在上一章节中我们把服务提供者Provider注册进了Consul&#xff0c;而本章节则是关于如何将服务消费者Consumer注册进Consul 1、再次创建一个服务提供者模块&#xff0c;命名为consumerconsul-order80 (1)在父工程下新建模块 (2)选择模块的项目类型为Maven并选…

2024LarkXR新增功能系列之九| 优化分配策略:增加GPU检查参数

Paraverse平行云实时云渲染解决方案LarkXR在2024年新增了优化分配策略&#xff0c;增强了GPU检查参数的能力&#xff0c;满足了复杂元宇宙/数字孪生场景多样性的可视化的需求&#xff0c;为这些应用找到了更好的解决方案。新版本的LarkXR在渲染请求分配策略上做出了显著的改进。…

币圈资讯Cryptosquare论坛

在加密货币世界中&#xff0c;信息的及时获取对于投资者和交易者至关重要。今天&#xff0c;我将向大家介绍Cryptosquare这个综合性资讯论坛&#xff0c;它汇集了币圈新闻、空投信息、社会热点以及与Web3相关的工作信息。让我们一起解锁加密世界的种种可能性&#xff0c;探索Cr…

创建SpringBoot和RabbitMQ的整合项目

文章目录 创建SpringBoot和RabbitMQ的整合项目首先快速创建一个maven项目引入SpringBoot整合rabbitMQ的依赖在src/main目录下创建resources目录并引入配置文件写消息发送者MessageSender写消息接收者MessageReceiver写RabbitMQConfig配置类写SpringBoot启动主类CommandLineRunn…