字典树 trie树 学习

2023-05-16

一字典树

字典树,又称单词查找树,Trie树,是一种树形结构,哈希表的一个变种
 
二.性质
根节点不包含字符,除根节点以外的每一个节点都只包含一个字符;

从根节点到某一节点,路径上经过的字符串连接起来,为该节点对应的字符串;

每个节点的所有子节点包含的字符都不相同。 

三.优势: 利用字符串的公共前缀,节约存储空间和查找时间。时间复杂度O(n)
 
四.适用于:快速字符串插入,查找字符串,在大量字符串的查找中,体现其高效性。
 
查找的时间复杂度只和树的深度有关,跟表中有多少个单词无关。
树的深度与单词的长度有关:
每个节点代表字符串下的一个字母,那么单词的每一个字母独占树的一层的位置,没有单词的两个字母在同一层级,
则整个树高为(最长字符串+1), + 1因为root 节点独占顶层
 
 
五.应用
 
(1)排序:
  排序:使用数组创建模拟字典树:将字母序列转化成数字序列 ,标记为数组索引,那么数组索引有序,字母即有序。( 参考上图,前序遍历即排序
对树进行前序遍历 就是有序排序了。
  
 (2)统计单词/字符串出现次数
       字典树的结构体:
       
   count即为统计的串出现的次数 
 
 (3) 查找公共前缀字符串
 
使用举例:

/*
 字典树学习:
 
 输入n个单词  举出一个单词出现的次数。
 
 10
 
 apple
 ppppp
 hello
 hello
 need
 bee
 bee
 none
 you
 apple
 
 
 need
 ==1
 ==Program ended with exit code: 0
 
 */
//
//  main.cpp
//  CPlusDemo
//
//  Created by HF on 2018/5/15.
//  Copyright © 2018年 HF-Liqun. All rights reserved.
//

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
using  namespace std;

#define MAX 26    //the total number of alphabet is 26, a...z

struct DicTrie{
    bool isTerminal;//是否是单词结束标志
    int  count;     //当前字符串出现次数
    struct DicTrie *next[MAX ]; //每个节点 最多 有 MAX 个孩子节点 结构体嵌套
}   ;

DicTrie *root = NULL; // 根节点是一个空节点 特此声明并赋值

int init()            //初始化链表,有对空间要求的 可选用该方法进行初始化
{
    root = new DicTrie;
    root->count = 0;
    for (int  i = 0; i < MAX; i ++) {
        root->next[i] = NULL; // 空节点
        root->isTerminal = false; //
    }
    return 0;
}

bool isFindTrie(char *targetString) //判断是否能在字典树中查到目标串
{
    int len = strlen(targetString);
    DicTrie *head = root;
    for (int i = 0; i < len; i ++) {
        int res = (int)(targetString[i] - 'a');//当前小写字母对应数字
        if (head->next[res] == NULL) { //如果是空节点 则为否 结束查找
            return false;
        } else {//不为空 更新头指针 以便继续往下查找
            head = head->next[res];
        }
    }
    if (head->count > 0) {
        return true;
    }
    return false;
}

int findTrieCount(char *targetString) //判断是否能在字典树中查到目标串
{
    int len = strlen(targetString);
    DicTrie *head = root;
    for (int i = 0; i < len; i ++) {
        int res = (int)(targetString[i] - 'a');//当前小写字母对应数字
        if (head->next[res] == NULL) { //如果是空节点 则为否 结束查找
            return false;
        } else {//不为空 更新头指针 以便继续往下查找
            head = head->next[res];
        }
    }
    return head->count;
}

int insertTrie(char *targetString)
{
    int len = strlen(targetString);
    DicTrie *head = root;
    for (int i = 0; i < len; i ++) {
        int res = (int)(targetString[i] - 'a');//当前小写字母对应数字
        if (head->next[res] == NULL) { //如果是空节点
            head->next[res] = new DicTrie;//则插入新节点元素
            head = head->next[res]; //更新头指针 并初始化
            head->count = 0;        //
            for (int j = 0; j < MAX; j ++) {
                head->next[j] = NULL;
                head->isTerminal = false;
            }
        } else {
            head = head->next[res];
        }
    }
    head->count ++;//每次插入一个,响应计数都增加1
    head->isTerminal = true;
    return head->count;
}

int deleteTrie(char *targetString)
{
    int len = strlen(targetString);
    DicTrie *head = root;
    for (int i = 0; i < len; i ++) {
        int res = (int)(targetString[i] - 'a');//当前小写字母对应数字
        if (head->next[res] == NULL) { //如果是空节点 表示删除的字符串不在字典中
            return 0;
        } else { //继续查找
            head = head->next[res];
        }
    }
    head->count --;//每次删除一个,响应计数都-1
    if (head->count <= 0) {
        head->count = 0;
        head->isTerminal = false;
    }
    return 0;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    int n;
    char targetString[20];
    
    init();
    
    scanf("%d",&n); //n 组数据
    for (int i = 0; i < n; i ++) {
        scanf("%s",targetString);
        //字符串插入字典树
        insertTrie(targetString);//插入方法
    }
    scanf("%s",targetString);
    printf("==%d\n",findTrieCount(targetString));//查找方法
    
    return 0;
}  

 

 参考
1.https://blog.csdn.net/piaocoder/article/details/47836559
2.http://blog.51cto.com/570842253/1556652
3.http://pisces.ck.tp.edu.tw/~peng/index.php?action=showfile&file=f743c2923f8170798f62a585257fdd8436cd73b6d
4.https://baike.baidu.com/item/%E5%AD%97%E5%85%B8%E6%A0%91/9825209?fr=aladdin&fromid=517527&fromtitle=Trie%E6%A0%91
 
 
 

转载于:https://www.cnblogs.com/someonelikeyou/p/9056664.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

字典树 trie树 学习 的相关文章

随机推荐

  • Spring Cloud Feign 请求动态URL

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 1 FeignClient 中不要写url 使用 64 RequestLine 修饰方法 2 调用地方必须引入 FeignClientConfiguration 必须有De
  • 折半查找:查找成功的最少/多次数、平均次数,查找不成功的最少/多次数、平均次数...

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 最方面的方法是建立一个判定树 现在有11个数 xff1a xff08 第1行是索引 xff0c 第2行是数 xff09 0 1 2 3 4 5 6 7 8 9 10 7 1
  • 关于maven打包 “程序包com.sun.deploy.net不存在” 的问题

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 关于maven打包 程序包com sun deploy net不存在 的问题 遇到问题如下 xff1a INFO payGateway 1 0 SNAPSHOT SUCCE
  • 印度理工学院有多难考?

    http app myzaker com news article php pk 61 599546401bc8e08604000085 印度理工学院有多难考 xff1f 何赟08 17 原文是六月高考季时给公众号 34 中印对话 34 x
  • iOS系统下 的手机屏幕尺寸 分辨率 及系统版本 总结

    今天 我对iOS系统下 的手机屏幕尺寸 分辨率 及系统版本做了一次系统总结 供大家参考 首先 是系统 xff1a 随着iOS 系统不断升级 xff0c 现在已经到iOS7 0了 xff0c 并且TA有了很多新变化 xff0c 最震撼的就是
  • android ViewFlipper的使用

    屏幕切换指的是在同一个Activity内屏幕见的切换 xff0c 最长见的情况就是在一个FrameLayout内有多个页面 xff0c 比如一个系统设置页面 xff1b 一个个性化设置页面 通过查看 OPhone API文档可以发现 xff
  • Linux下路由配置梳理

    在日常运维作业中 xff0c 经常会碰到路由表的操作 下面就linux运维中的路由操作做一梳理 xff1a 先说一些关于路由的基础知识 xff1a 1 xff09 路由概念 路由 xff1a 跨越从源主机到目标主机的一个互联网络来转发数据包
  • ASP.NET成员角色系列(一)--验证与授权入门

    在当今的信息世界里 无论是门户网站 电子商务 社区论坛 都有一个共性 它们通常都需要验证当前用户的身份并根据验证结果判断用户所具有的权限 例如博客园 它允许未注册的匿名用户可能查看帖子 但是不允许他们发表帖子 为了能够发表帖子 匿名用户必须
  • 老赵谈IL(4):什么时候应该学IL,该怎么学IL

    又是一个拖了半年的系列 xff0c 可能是前几篇主要以事实为准 xff0c 举例子的文章总是比较容易写的 xff0c 因此十分顺畅 而最后一篇打算做一个总结 xff0c 以讲道理为主 却发现该将的似乎都已经讲完了 不过做事要有始有终 xff
  • FreeRTOS的第一个任务是怎么跑起来的

    一 一般在程序末尾会有一个vTaskStartSheduler 函数 span class hljs keyword int span main span class hljs keyword void span BSP INIT Bina
  • STM32-正弦波可调(50HZ~20KHZ可调、峰峰值0~3.3V可调)

    1 原理 通过定时器每隔一段时间触发一次DAC转换 然后通过DMA发送正玄波码表值给DAC 当需要改变频率HZ 时 只需要修改定时器频率 即可 最高只能达到20KHz 当需要改变 正玄波的正峰峰值 负峰峰值 时 只需要修改正玄波码表 即可
  • .Net ASP.NET 打开指定文件夹

    比如要打开指定的文件夹 xff0c 而不是弹出对话框 System Diagnostics Process Start 64 34 D 34 这样就打开了D盘 和正常打开D盘是一样的
  • 几种更新(Update语句)查询的方法

    正 文 数据库更新就一种方法Update xff0c 其标准格式 xff1a Update 表名 set 字段 61 值 where 条件 只是依据数据的来源不同 xff0c 还是有所差别的 xff1a 1 从外部输入 这样的比較简单 例
  • mysql8.0.13 cmd 登陆报错

    今天打算配置一个php运行环境 xff0c 将php mysql apache依次下载好 xff0c 我首先安装的是mysql xff0c 安装过程很顺利 xff0c 在cmd输入mysql uroot p的时候 xff0c 我靠 xff0
  • vue移动端的自适应布局的两种解决方案

    目标 前端开发移动端及H5时候 xff0c 不需要再关心移动设备的大小 xff0c 只需要按照固定 设计稿的px值布局 基础知识 dpr xff08 设备像素比 xff09 css的像素px不等于设备像素 分辨率 各种值 xff0c css
  • 对单片机数码管显示段选位选的理解

    在51单片机的数码管的应用开发中一些小的细节还是应该注意到的 其中位选信号应该在段选之前打开 xff0c 下面是一段示例代码 xff08 我用的是国信长天开发板 xff09 xff1a include lt reg51 h gt 包含51单
  • http请求中get请求可以缓存和post请求不可缓存

    2019独角兽企业重金招聘Python工程师标准 gt gt gt GET请求后退 刷新无害 xff0c POST后退 刷新则会导致重新提交数据 GET书签可被收藏 POST为书签不可收藏 GET能被缓存 POST不能被缓存 GET编码类型
  • VMWare中虚拟机(CentOS)如何开启虚拟化功能

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 需求说明 xff1a VMware版本如下示 xff0c 在此VMware上创建了虚拟机并安装了CentOS6 5系统 现在需要在此客户机 xff08 VM xff09 上
  • C# 常见的错误类型

    Exception 应用程序执行期间发生错误 SystemException 系统异常 所有Exception的基类 ArgumentException 当方法提供的任意一个参数无效时 xff0c 引发此异常 ArithmeticExcep
  • 字典树 trie树 学习

    一字典树 字典树 xff0c 又称单词查找树 xff0c Trie树 xff0c 是一种树形结构 xff0c 哈希表的一个变种 二 性质 根节点不包含字符 xff0c 除根节点以外的每一个节点都只包含一个字符 xff1b 从根节点到某一节点