一 概述

又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。

二 优点

利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。

三 性质

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

单词列表为”apps”,”apply”,”apple”,”append”,”back”,”backen”以及”basic”对应的字母树可以是如下图所示。

例如,保存”apple”和 “apply”时,由于它们的前四个字母是相同的,所以希望它们共享这些字母,而只对剩下的部分进行分开存储。可以很明显地发现,字母树很好地利用了串的公共前缀,节约了存储空间。

四 应用

(1)串的快速检索

给出N个单词组成的熟词表,以及一篇全用小写英文书写的文章,请你按最早出现的顺序写出所有不在熟词表中的生词。 
在这道题中,我们可以用数组枚举,用哈希,用字典树,先把熟词建一棵树,然后读入文章进行比较,这种方法效率是比较高的。

(2)“串”排序

给定N个互不相同的仅由一个单词构成的英文名,让你将他们按字典序从小到大输出用字典树进行排序,采用数组的方式创建字典树,这棵树的每个结点的所有儿子很显然地按照其字母大小排序。对这棵树进行先序遍历即可。

(3)最长公共前缀

对所有串建立字典树,对于两个串的最长公共前缀的长度即他们所在的结点的公共祖先个数,于是,问题就转化为当时公共祖先问题。

五 实现

字典树的插入(Insert)、删除( Delete)和查找(Find )都非常简单,用一个一重循环即可,即第 i 次循环找到前 i 个字母所对应的子树,然后进行相应的操作。实现这棵字典树,我们用最常见的数组保存即可,当然也可以开动态的指针类型。至于结点对儿子的指向,一般有三种方法: 
(1)对每个结点开一个字母集大小的数组,对应的下标是儿子所表示的字母,内容则是这个儿子对应在大数组上的位置,即标号; 
(2)对每个结点挂一个链表,按一定顺序记录每个儿子是谁; 
(3)使用左儿子右兄弟表示法记录这棵树。 
三种方法,各有千秋。第一种易实现,但实际的空间要求较大;第二种, 
较易实现,空间要求相对较小,但比较费时;第三种,空间要求最小,但相对费时且不易写。但总的来说,几种实现方式都是比较简单的,只要在做题时加以合理选择即可。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;#define MAX 26struct TrieNode{// 以该节点为结尾的单词个数int count;TrieNode *next[MAX];TrieNode(int x):count(x){for(int i = 0;i < MAX;++i){next[i] = NULL;}//for}
};
// 插入
void Insert(TrieNode* &root,string str){int size = str.size();int val;TrieNode *p = root;// 一个一个字符插入for(int i = 0;i < size;++i){val = str[i] - 'a';// 之前没有该字符if(p->next[val] == NULL){p->next[val] = new TrieNode(0);}//ifp = p->next[val];}//for// 以该字符为结尾p->count++;
}
// 删除
void Delete(TrieNode* &root,string str){int size = str.size();int val;TrieNode *p = root;// 一个一个字符插入for(int i = 0;i < size;++i){val = str[i] - 'a';// 删除的字符串不在字典中if(p->next[val] == NULL){return;}//ifp = p->next[val];}//for// 以该字符为结尾p->count--;
}
// 查找
bool Search(TrieNode* root,string str){if(root == NULL){return false;}//ifint size = str.size();TrieNode *p = root;int val;for(int i = 0;i < size;++i){val = str[i] - 'a';// 无法转移到下一个字符if(p->next[val] == NULL){return false;}//if// 继续下一个字符p = p->next[val];}//forreturn p->count > 0;
}
// 打印字典
void PrintDic(TrieNode* root,vector<vector<char> > &words,vector<char> &word){if(root == NULL){return;}//ifif(root->count > 0){words.push_back(word);}//iffor(int i = 0;i < 26;++i){if(root->next[i]){word.push_back('a'+i);PrintDic(root->next[i],words,word);word.pop_back();}//if}//for
}int main() {TrieNode* root = new TrieNode(0);// 插入string strs[] = {"ok","applition","app","apple","apply"};for(int i = 0;i < 5;++i){Insert(root,strs[i]);}//forstring str("apple");cout<<"删除单词["<<str<<"]之前查询结果:"<<endl;// 查询if(Search(root,str)){cout<<"单词["<<str<<"]在字典中"<<endl;}//ifelse{cout<<"单词["<<str<<"]不在字典中"<<endl;}cout<<"删除单词["<<str<<"]"<<endl;// 删除Delete(root,str);cout<<"删除单词["<<str<<"]之后查询结果:"<<endl;// 查询if(Search(root,str)){cout<<"单词["<<str<<"]在字典中"<<endl;}//ifelse{cout<<"单词["<<str<<"]不在字典中"<<endl;}// 字典列表cout<<"字典列表:"<<endl;vector<vector<char> > words;vector<char> word;PrintDic(root,words,word);for(int i = 0;i < words.size();++i){for(int j = 0;j < words[i].size();++j){cout<<words[i][j];}//forcout<<endl;}//forreturn 0;
}

六 引用

字典树Trie

算法合集之《浅析字母树在信息学竞赛中的应用》

字典树查询时间复杂度相关推荐

  1. Trie字典树(1)—— 字典树查询

    1 Trie 介绍 1.1 字典 如果有 n 个条目,使用树结构,查询的时间复杂度是 O(logn); 如果有100 万个条目(2^20),logn 大约数20 1.2 Trie 查询每个条目的时间复 ...

  2. 字典树(tire树)

    字典树功能: 给定n个主串平均长度为len1,m个模式串平均长度为len2,问m个模式串分别在n个字符串中出现了几次? 首先如果用kmp算法,对于n个主串每个主串都和m个模式串进行比较,那么对于每一个 ...

  3. 字典树(前缀树)-Java实现

    字典树 字典树是一种树形结构,优点是利用字符串的公共前缀来节约存储空间.在这提供一个自己写的Java实现,非常简洁. 根节点没有字符路径.除根节点外,每一个节点都被一个字符路径找到. 从根节点到某一节 ...

  4. 字典树实现_反怼面试官系列之 字典树

    一.简介 Trie 树也称为字典树.单词查找树,最大的特点就是共享字符串的公共前缀来达到节省空间的目的. 例如,字符串 "abc" 和 "abd" 构成的 tr ...

  5. 可持久化-可持久化字典树

    可持久化-Trie可持久化 2021年8月2日 可持久化干什么? 可持久化,就是记录每次更改的版本,以便于后续使用从前的版本.对于字典树,就是对每次加入的字符串按次进行记录. 算法原理 建树时,每次新 ...

  6. POJ 3764 Language: The xor-longest Path (01字典树+DFS)

    传送门:POJ 3764 题目大意: 在树上找一段路径(连续)使得边权相异或的结果最大. 前置技能: 1.用链式前向星建图. 2. 01字典树的应用. 思路: 本题用 vector数组建图是会超时的, ...

  7. 字典树在车站查询功能中的应用

    1.在12306的火车票订票系统中,当我们在出发地或者目的地框中输入一个汉语拼音的简写时,就会出现相应的地名.如输入"wh"就会出现"武汉","威海& ...

  8. python实现字典树 时间复杂度_Python实现字典树

    字典树,又称单词查找树,Trie 树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:利用字符串 ...

  9. 【Hihocoder - offer编程练习赛39 - D】前缀后缀查询(后缀字典树,哈希,思维)

    题干: 时间限制:10000ms 单点时限:1000ms 内存限制:512MB 描述 给定一个包含N个单词的字典:{W1, W2, W3, ... WN},其中第i个单词Wi有具有一个权值Vi. 现在 ...

最新文章

  1. java 外来类,外来的Matplotlib图(tkinter中的情节)
  2. 【转载】Eclipse 最常用快捷键 (动画讲解),最简单的一些快捷键
  3. 低电压瞬态抑制二极管,有哪些常用的型号?
  4. BugKuCTF WEB web基础$_POST
  5. cadence中元件所在库
  6. python是脚本语言_Python 脚本语言
  7. ORACLE常用函数汇总【转】
  8. python数据驱动读取用例_利用Python如何实现数据驱动的接口自动化测试
  9. nginx发布PHP代码,nginx服务器配置返回php代码
  10. futuretask java_Java并发编程一(FutureTask)
  11. 接口测试-jmeter
  12. TZOJ 数据结构期末历年题目
  13. 终端的乐趣--Linux下有趣的终端命令或者工具
  14. Waymo上线11万美元挑战赛,福特开放1.6TB自动驾驶数据
  15. 2022年电子造粒计数器市场前景分析及研究报告
  16. Zabbix 5.0 监控教程(一)
  17. html制作简易计算机,用JavaScript制作一个简易计算器
  18. ISIS几个命令的区别
  19. Android USB编程
  20. 搭建阿里云服务器的步骤

热门文章

  1. 浅学C#(2)——CLR的概念和功能
  2. 无敌铁金刚游戏UI资源破解版下载
  3. 快狠准!面试5分钟自我介绍法
  4. 用PS的照片申请理赔,保险公司能过吗?
  5. 攻防世界 reverse新手题 game
  6. python自动化测试生成报告_使用python测试框架完成自动化测试并生成报告-实例练习...
  7. 基于Android的景点导游
  8. Arbitrary Style Transfer in Real-time with Adaptive Instance Normalization论文阅读笔记
  9. 基于深度学习的安全帽检测系统(YOLOv5清新界面版,Python代码)
  10. 海康摄像头二次开发python_python实现海康sdk二次开发,移动侦测事件(一)