字典树是一种存储字符串的高效的结构,它保存了不同字符的相同前缀,又因此叫做前缀树,使用前缀,大大避免相同字符的重复匹配,加快查找效率

  • 字典树是一颗多叉树,比如存储26个字母的,那么就有26叉
  • 字典树的节点不存储字符,而是用树的边来存储字符
  • 字典树的每一个节点都对应着一个字符子串
  • 字典树的叶子节点对应的字符串是创建字典树的字符串集合里的元素

如图:使用 5 个字符串创建字典树,蓝色节点代表子串,红色节点表示集合里的字符串(或者说字典树的叶子节点表示完整的字符串)

["apple", "apk", "kksk", "kkp", "boki"]

结构定义

可以快速的定义一个26叉树

/*
isEnd 表示是否是叶子节点
s 表示当前节点代表的字符串
*/
class node
{public:bool isEnd;string s;node* childs[26];node(){s=""; isEnd=false; for(int i=0; i<26; i++)childs[i]=NULL;}
};

插入元素

对于长度为n的字符串,我们依次遍历元素,从根节点开始,比如第一个字符是 ‘a’,那么查找根节点是否有 ‘a’ 的子树

  • 如果有,转到那个子树
  • 如果没有,创建新的子树,再转到

最后遍历结束时,记得把叶子节点的 isEnd 置一

void insert(node* &root, string s)
{node* p = root;for(int i=0; i<s.length(); i++){if(p->childs[s[i]-'a']) p=p->childs[s[i]-'a'];else{node* nd = new node();nd->s = p->s + s[i];p->childs[s[i]-'a'] = nd;p = nd;}}p->isEnd = true;
}

查找

查找与插入类似,从左往右遍历要查找的字符串,先找有没有对应的子树,如果有,直接转到,如果没有,返回false

遍历完成之后,记得检查当前节点的 isEnd 标志,如果为true,说明查找成功

bool search(node* root, string s)
{node* p = root;for(int i=0; i<s.length(); i++){if(p->childs[s[i]-'a']) p=p->childs[s[i]-'a'];else return false;}return p->isEnd;
}

遍历

层次遍历,没啥好说的。。

void show(node* root)
{if(!root) return;deque<node*> q;q.push_back(root);while(!q.empty()){int qs = q.size();for(int i=0; i<qs; i++){node* tp=q.front(); q.pop_front();cout<<tp->s<<" ";for(int i=0; i<26; i++)if(tp->childs[i]) q.push_back(tp->childs[i]);}cout<<endl;}
}

对字典树先序遍历可以得到所有字符串的升序排序的结果

void dlrSort(node* root)
{if(!root) return;if(root->isEnd) {cout<<root->s<<" "; return;}for(int i=0; i<26; i++) dlrSort(root->childs[i]);
}

完整代码

#include <bits/stdc++.h>using namespace std;class node
{public:bool isEnd;string s;node* childs[26];node(){s=""; isEnd=false; for(int i=0; i<26; i++)childs[i]=NULL;}
};void insert(node* &root, string s)
{node* p = root;for(int i=0; i<s.length(); i++){if(p->childs[s[i]-'a']) p=p->childs[s[i]-'a'];else{node* nd = new node();nd->s = p->s + s[i];p->childs[s[i]-'a'] = nd;p = nd;}}p->isEnd = true;
}bool search(node* root, string s)
{node* p = root;for(int i=0; i<s.length(); i++){if(p->childs[s[i]-'a']) p=p->childs[s[i]-'a'];else return false;}return p->isEnd;
}void show(node* root)
{if(!root) return;deque<node*> q;q.push_back(root);while(!q.empty()){int qs = q.size();for(int i=0; i<qs; i++){node* tp=q.front(); q.pop_front();cout<<tp->s<<" ";for(int i=0; i<26; i++)if(tp->childs[i]) q.push_back(tp->childs[i]);}cout<<endl;}
}void dlrSort(node* root)
{if(!root) return;if(root->isEnd) {cout<<root->s<<" "; return;}for(int i=0; i<26; i++) dlrSort(root->childs[i]);
}int main()
{node* root = new node();int t; cin>>t;while(t--){string s; cin>>s;insert(root, s);}cout<<endl<<"insert finished, show tree :"<<endl;show(root);cout<<endl<<"end of show tree"<<endl;cin>>t;while(t--){string s; cin>>s;cout<<search(root, s)<<endl;}cout<<"sort"<<endl;dlrSort(root);cout<<endl;return 0;
}
/*
sample input :
5
apple apk kksk kkp boki
*/

以上代码会产生以下结果,生成树如下:

字典树简单实现 插入 查找 遍历相关推荐

  1. c语言 trie树,C语言实现Trie树(字典树)的插入查找删除与遍历操作

    Trie树,也称作是字典树,是一种哈希树的变种,查询效率较高.Trie树可以用于统计或者排序大量的字符串,比如对一系列字符串按照字典序排序. 字典树是一个多叉树,每一个节点上存储的不是一个字符串,而是 ...

  2. Algorithm:树结构(二叉树/多路查找树/字典树)的简介、具体结构(FBT/CBT/BST/BBT/Heap/Huffman、B树/B+树/R树、字典树)及其运算(增删查/遍历/旋转)、代码实现

    Algorithm:树结构(二叉树/多路查找树/字典树)的简介.具体结构(FBT/CBT/BST/BBT/Heap/Huffman.B树/B+树/R树.字典树)及其运算(增删查/遍历/旋转).代码实现 ...

  3. 线段树的创建插入查找删除

    一.线段树基本概念 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点.     对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间 ...

  4. 【字典树】添加和查找单词

    为什么80%的码农都做不了架构师?>>>    Add and Search Word - Data structure design 问题: Design a data struc ...

  5. 数据结构与算法(十一)Trie字典树

    本文主要包括以下内容: Trie字典树的基本概念 Trie字典树的基本操作 插入 查找 前缀查询 删除 基于链表的Trie字典树 基于Trie的Set性能对比 LeetCode相关线段树的问题 Lee ...

  6. 012-数据结构-树形结构-哈希树[hashtree]、字典树[trietree]、后缀树

    一.哈希树概述 1.1..其他树背景 二叉排序树,平衡二叉树,红黑树等二叉排序树.在大数据量时树高很深,我们不断向下找寻值时会比较很多次.二叉排序树自身是有顺序结构的,每个结点除最小结点和最大结点外都 ...

  7. 用Python实现字典树(Trie)与双数组字典树(DATrie)

    1. 字典树(Trie) 假如我们把字典中的词以记录的形式(无序)存入数据库中.现给定一串字符,要查找该字符串是否为字典中的词.因为数据库中的记录是无序的,所以,最朴素的方法就逐记录匹配.此方法简单, ...

  8. 字典树(java实现)

    字典树(java实现) 一.概念: Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于 ...

  9. 【转】从Trie树(字典树)谈到后缀树

    本文第一部分,咱们就来了解这个Trie树,然后自然而然过渡到第二部分.后缀树,接着进入第三部分.详细阐述后缀树的构造方法-Ukkonen. 第一部分.Trie树 1.1.什么是Trie树 Trie树, ...

最新文章

  1. 网络规划设计培训与方案集下载
  2. cnzz统计代码引起的Bad Request - Request Too Long
  3. python邮件图片加密_Python爬虫如何应对Cloudflare邮箱加密
  4. pixelbook安装linux系统,谷歌Pixelbook可以运行Fuchsia操作系统 正测试
  5. 白--留白与游戏设计
  6. 1.KafKa-介绍
  7. java bitset_Java BitSet or()方法与示例
  8. 我是如何走上前端开发这条路 并常年保持一线竞争力的
  9. 2018-06-18
  10. mysql词法分析antlr4_sharding-jdbc之ANTLR4 SQL解析
  11. PAT 1090 危险品装箱(25 分)- 乙级
  12. [译] Redux vs. React 的 Context API
  13. 2021线报天下 原创工具 (免费版本,无版权问题)
  14. Macbook Pro 安装 win10 单操作系统
  15. 北京大学计算机801考试大纲,2019年中国科学院大学801高等代数考研初试大纲
  16. WinCC RT Adv 项目下载与自动运行
  17. React上拉加载和下拉刷新
  18. 新手主播在一对一视频直播平台更容易发展,轻松月入过万!
  19. AliOS-Things--ESP8266-linkkitapp-配网(一)
  20. about a day and a story

热门文章

  1. 计算机应用EXCEL之数据看板制作
  2. java 本地缓存框架_5个强大的Java分布式缓存框架推荐
  3. 电脑开两个微信_电脑上登录两个微信或是多个微信?
  4. GaitSet论文复现中遇到的部分问题解决(CASIA-B数据集)
  5. NODE_npm发布轮子
  6. 6678开发板NDK网口通信完整实现(附源码)
  7. 同花顺软件“股本结构.财经”文件格式分析
  8. 碳刷滑环在发电机中的作用
  9. 简单汽车售票管理系统
  10. 正阳-本站汇总(长期更新)