数据结构学习:Trie树

news2024/11/27 1:27:21

Trie

    • 一、概念
    • 二、代码实现
    • 三、Tire树的时间复杂度和空间复杂度
    • 四、Tire树的优势

一、概念

  • Trie树,也叫"字典树",顾名思义,是一种专门处理字符串匹配的树形结构,用来解决在一组字符串集合中快速找到某个字符串
  • 类似于这种字符串匹配问题,可以使用RF暴力匹配、RK哈希匹配、散列表、红黑树等,但Trie树有它特有的优势

在这里插入图片描述

  • 如上图所示,就是一颗Trie树,头节点’/'是无意义字符,节点存储了hi、how、see、so、her、hello等单词;
  • 可以看到Tire树就是利用字符串的公共前缀,将公共前缀存储在一起

二、代码实现

可以看到,Tire树是一颗多叉树,二叉树可以每个节点存储左右节点的指针,那多叉树怎么存储呢?

  • 可以利用散列表的思想,利用一个数组和下标来存储子节点的指针
package StringMatch;

/*
    Trie树
 */
public class Trie_zhu {
    private TrieNode head = new TrieNode('/'); //头节点,存储无意义字符

    static class TrieNode{
        private char value;
        private TrieNode[] Children = new TrieNode[26];
        private boolean isEnding = false;

        public TrieNode(char value){
            this.value = value;
        }
    }

    public void insert(String value){
        TrieNode p = head;
        char[] text = value.toCharArray();
        for (int i = 0; i < text.length;i++){
            int index = text[i] - 'a';
            if (p.Children[index] == null){
                TrieNode newNode = new TrieNode(text[i]);
                p.Children[index] = newNode;
            }
            p = p.Children[index];
        }
        p.isEnding = true;
    }

    public boolean find(String value){
        char[] text = value.toCharArray();
        TrieNode p = head;
        for (int i = 0; i < text.length;i++){
            int index = text[i] - 'a';
            if (p.Children[index] == null){
                return false;
            }
            p = p.Children[index];
        }
        return p.isEnding;
    }
}

三、Tire树的时间复杂度和空间复杂度

如果要在一组字符串中,频繁地查询某些字符串,用Trie树会非常高效,

  • 构建trie树:需要扫描所有的字符串,时间复杂度为O(n),(n表示所有字符串的长度和)
  • 查询trie树:如果要查询的字符串长度为k,那么只需要比对k个节点,就能完成查询操作,时间复杂度为O(k)

Trie对于匹配字符串的效率是很高的,但是会比较耗内存,是一种"空间换时间"的思路

  • Trie树在实现的时候,如果是用数组,且字符串中包含’a’-'z’这26个字符,那每个节点都要存储一个长度为26的数组,并且每个数组元素还需要维护指针
  • Trie树的本质是避免重复存储一组字符串的相同的前缀子串,但是现在每个字符(对应一个节点)的存储远远大于1个字节,而且,如果字符串中不仅包含小写字母,还包含大写字母、数字甚至是中文,重复前缀也不多,trie树不仅不能节省内存,还有可能浪费更多的内存

四、Tire树的优势

在一组字符串中查找某个字符串,Trie树表现的并不好,它对要处理的字符串有极其严苛的要求

  • 字符串中的字符集不能太大,如果字符集太大,存储空间就会浪费很多
  • 要求字符串的前缀重合比较多,不然空间消耗会大很多
  • 如果要用Trie树解决问题,那我们就要从零开始实现一个Trie树,还要保证没有bug,这是在将简单的问题复杂化
  • 通过指针串起来的数据块是不连续的,而Trie树中用到了指针,对缓存并不友好,性能上会打折扣

因此,这种问题更适合用红黑树或散列表来解决
Trie树的优势在于查找前缀匹配的字符串,比如浏览器中输入object,会跳出相关选项
在这里插入图片描述
还包括一些自动输入补全,比如输入法自动补全功能、IDE代码编辑器自动补全等

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

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

相关文章

RabbitMQ 快速入门七种简单模式

RabbitMQ 快速入门七种简单模式起步七种模式项目依赖1、"Hello World!"(1) Connection 方式(2) RabbitTemplate 方式2、Work Queues生产者消费者3、Publish/Subscribe关系绑定生产者消费者4、Routing消费者生产者5. Topics消费者生产者6、RPC7、Publisher Confirms起…

面试又卡在多线程?那就来分享几道 Java 多线程高频面试题,面试不用愁

多线程中的忙循环是什么?忙循环就是程序员用循环让一个线程等待&#xff0c;不像传统方法 wait()、 sleep() 或 yield()&#xff0c;它们都放弃了 CPU 控制&#xff0c;而忙循环不会放弃 CPU&#xff0c;它就是在运行一个空循环。 这么做的目的是为了保留 CPU 缓存&#xff0c…

用于大规模 MIMO 检测的近似消息传递 (AMP)(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

【二开】mattermos扩展第三方登录

目录 前景提要明确目标开始动手部署开发环境找到项目入口梳理登录流程修改请求地址前景提要 公司准备使用mattermost,项目进行任务管理,我们需要让已有系统能够对接该系统的登录。 明确目标 前端webApp项目独立部署使用第三方Token可以通过使用第三方Token登录mattermost平…

因子模型:套利定价理论APT

本文是Quantitative Methods and Analysis: Pairs Trading此书的读书笔记。 因子模型(factor models)用来解释资产的风险或者回报的特点。在CAPM模型中&#xff0c;资产的回报几乎就是由市场决定的&#xff0c;每个资产对市场的敏感程度可以用beta来描述。因而&#xff0c;在C…

RabbitMQ系列【18】对象序列化机制

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录前言发送对象接收对象使用Jackson 序列化前言 使用RabbitMQ原生API&#xff0c;发送消息时&#xff0c;发送的是二进制byte[]数据。 void basicPublish(String var1, String var2, byte[] var4…

1.2 监督学习

1.2 监督学习监督学习的定义监督学习的相关概念监督学习流程图监督学习的定义 监督学习(Supervised Learning&#xff09;是指从标注数据中学习预测模型的机器学习问题&#xff0c;其本质是学习输入到输出的映射的统计规律。 输入空间 (Input Space&#xff09;&#xff1a;输…

11.29总结

目录 一.连续子数组最大和 方法2动态规划 二.查找最小的k对数字 一.从先序遍历还原二叉树 二.完全二叉树 三.判断对称二叉树 四 回文 五.连续子数组最大和 六.TopK问题 思路一如果数据特别大.排序的时间复杂度会很大 思路二:用大根堆或者小根堆然后分别弹出. 思路三…

CANoe-vTESTstudio之State Diagram编辑器(功能介绍)

1. 阶段 State Diagram从测试设计到测试执行,分为4个阶段: Test Design 在测试设计期间,测试设计人员使用图形元素和分配的测试代码来对要测试的SUT的状态和转换进行建模。这个阶段的结果是生成状态图 Evaluation 在评估期间,将验证各个元素及其关系并创建路径。评估产…

SpringBoot中如何实现业务校验,这种方式才叫优雅!

大家好&#xff0c;在日常的接口开发中&#xff0c;为了保证接口的稳定安全&#xff0c;我们一般需要在接口逻辑中处理两种校验&#xff1a; 参数校验 业务规则校验 首先我们先看看参数校验。 参数校验 参数校验很好理解&#xff0c;比如登录的时候需要校验用户名密码是否为…

Opencv边缘检测、轮廓发现、绘制轮廓

Opencv边缘检测、轮廓发现、绘制轮廓 提取图像轮廓的2个步骤 1、 findContours函数找轮廓&#xff0c; 2、 drawContours函数画轮廓 轮廓的查找——cv::findContours() 函数cv::findContour是从二值图像中来计算轮廓的&#xff0c;它可以使用cv::Canny()函数处理的图像&am…

【华为上机真题 2022】字符串分隔

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

Java---线程详解(并发并行,Thread类,Runnable接口,同步机制,线程死锁......)

目录 一、概念 1、进程 2、线程 &#xff08;1&#xff09;单线程 &#xff08;2&#xff09;多线程 &#xff08;3&#xff09;并发 &#xff08;4&#xff09;并行 二、线程基本使用 1、创建线程的两种方式 &#xff08;1&#xff09;继承Thread类 &#xff08;2&am…

esp8266用arduino连上阿里云(图文操作,100%成功)

最近学习了esp8266/esp32单片机。第一次使用arduino这个IDE&#xff0c;搞多了Keil5&#xff0c;这个实在是有点不习惯。进步都是困难的&#xff0c;现在回想起来&#xff0c;发现也没多难&#xff0c;回到正题。 准备软件&#xff1b;Arduino IDE 准备硬件&#xff1a;esp82…

面试:插件化相关---activity

我们先来看下Android常规Activity的启动流程 如何评价360的Android插件化框架RePlugin&#xff1f; - 知乎 1、调用Context.startActivity -> ActivityManagerProxy -> AMS, AMS通过Intent从PMS拿到ActivityInfo并创建ActivityRecord和token放入前台ActivityStack&…

macOS端React的项目WebPack热更新(HMR)失效问题分析及解决,原因竟是Windows文件系统不区分大小写导致

项目场景&#xff1a; 最近做的项目是一个使用UmiJS搭建的React的前端老项目&#xff0c;项目是上一个开发团队遗留下来的老项目&#xff0c;我们接着在原来的基础上开发。团队成员中有的是Windows电脑&#xff0c;有的是Mac电脑&#xff0c;所以存在规范不统一的情况。 问题描…

[附源码]计算机毕业设计springboot基于web的建设科技项目申报管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

微服务框架 SpringCloud微服务架构 5 Nacos 5.6 环境隔离

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构5 Nacos5.6 环境隔离5.6.1 环境隔离 - namespace5.6.2 使用 namespace5.6.…

Python的PyQt框架的使用-创建主窗体篇

Python的PyQt框架的使用-构建环境篇一、前言二 、创建主窗体一、前言 个人主页: ζ小菜鸡大家好我是ζ小菜鸡&#xff0c;小伙伴们&#xff0c;让我们一起来学习Python的PyQt框架的使用。如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连) 二 、创建主窗体 &#xff08;1&am…

【Linux】高频指令及简单的vim使用(0基础带你快速入门)

目录 一、目录操作指令 1.1、ls 1.2、pwd 1.3、cd 1.4、touch 1.5、cat 1.6、echo 1.7、mkdir 1.8、rm 1.9、mv 1.10、cp 二、Linux中如何手动安装插件 三、vim 3.1、打开文件 3.2、编辑文件 3.3、保存退出 一、目录操作指令 1.1、ls 语法&#xff1a; 第一种&#…