浅谈 trie树 及其实现

定义又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,

如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树。

核心思想:是空间换时间.利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

三个基本性质:

1. 根结点不包含字符,除根结点外每一个结点都只包含一个字符。

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

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

优点:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。

缺点:如果存在大量字符串且这些字符串基本没有公共前缀,则相应的trie树将非常消耗内存。

典型应用:统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计

至于Trie树的实现,可以用数组,静态分配空间,也可以用指针动态分配

Trie树的操作

在Trie树中主要有3个操作,插入、查找和删。一般情况下Trie树中很少存在删除单独某个结点的情况,因此只考虑删除整棵树。

假设存在字符串str(都为小写字母),Trie树的根结点为root。i=0,p=root。

typedef struct stu
{int n,flag;         //n记录前缀及单词的个数,flag标记单词是否存在struct stu *next[26];          //子节点
}node;
View Code
node* creat_node()
{node *p=(node *)malloc(sizeof(node));p->n=p->flag=0;memset(p->next,0,sizeof(p->next));return p;
}
建立新节点并初始化

1、插入

  1)取str[i],判断p->next[str[i]-'a']是否为空,若为空,则建立结点temp,并将p->next[str[i]-'a']指向temp,然后p指向temp;

   若不为空,则p=p->next[str[i]-'a'];

  2)i++,继续取str[i],循环1)中的操作,直到遇到结束符'\0',此时将当前结点p中的 flag 置为true。

void trie_insert(node *p,char *s)
{int i;while(*s!='\0'){i=*s-'a';if(p->next[i]==0)p->next[i]=creat_node();p=p->next[i];s++;p->n++;}p->flag=1;
}
插入字符串

2、查找

  1)取str[i],判断判断p->next[str[i]-'a']是否为空,若为空,则返回false;若不为空,则p=p->next[str[i]-'a'],继续取字符。

  2)重复1)中的操作直到遇到结束符'\0',若当前结点p不为空并且 flag 为true,则返回true,否则返回false。

int trie_search(node *p,char *s)
{int i;while(*s!='\0'){i=*s-'a';p=p->next[i];if(p==0)return 0;s++;}return p->n;
}
查找字符串,并返回其个数

3、删除

  删除可以以递归的形式进行删除。

void trie_del(node *root)
{int i;for(i=0;i<M;i++)                     //M为子节点的个数if(root->next[i]!=NULL)trie_del(root->next[i]);free(root);
}
递归删除整棵树

 

 

转载于:https://www.cnblogs.com/happy-lcj/p/3890417.html

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

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

相关文章

Docker-compose 安装与基本使用(四)

安装 Docker-Compose Compose有多种安装方式,例如通过 shell, pip以及将 Compose作为容器安装等。本次安装以Shell 为主。 通过以下命令自动下载并安装适应系统版本的 Compose: curl -L "https://github.com/docker/compose/releases/download/1.10.0/docker-compose-$(un…

如何开始DDD(完)

连续写了两篇文章&#xff0c;这一篇我想是序的完结篇了。结合用户注册的例子再将他简单丰富一下。在这里只添加一个简单需求&#xff0c;就是用户注册成功后给用户发一封邮件。补充一下之前的代码 public class DomainService {public void Register(User user){if (_userRepo…

git pull 报错:Untracked Fles Preventing Merge

场景 使用 git pull 命令更新报错解决 找到对应的文件删除后重新打开项目。

关于string,我今天科普的

今天下午朋友讨论组上讨论一个关于string的问题&#xff0c;问题是这样的&#xff0c;string a"aaa";string ba;a"bbb",为什么测试b的值不改变&#xff1f;之前我看过一个文章&#xff0c;知道肯定不相等&#xff0c;因为引用地址的一系列问题&#xff0c;…

git pull 报错:The following untracked working tree files would be overwritten by merge

场景 使用 git pull 命令更新报错 Updating d652d1c..fa05549 error: The following untracked working tree files would be overwritten by merge:.idea/encodings.xmlPlease move or remove them before you can merge. Aborting 解决 使用 git clean -d -fx 命令即可。

SpringBoot 配置多数据源

项目Git地址&#xff1a;SpringBoot 配置多数据源&#xff1a;Jacob-multi-data-source 准备工作 准备两个数据库(此模块中两个数据库一个为本地 一个为远程&#xff0c;本地为主&#xff0c;远程为从)。然后建表。 #本地库 CREATE TABLE username (id bigint(11) NOT NULL AUT…

HDU 2912

直线关于球的多次反射&#xff0c;求最后一次反射点 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath>using namespace std; const double inf1e10; const double eps1e-8; struct point {doub…

EMVTag系列3《持卡人基本信息数据》

9F61 持卡人证件号 L&#xff1a;2–26 R&#xff08;需求&#xff09;&#xff1a;数据应存在&#xff0c;在读应用数据过程中&#xff0c;终端不检查&#xff1b; (PBOC2.0第五部分中规定)芯片中持卡人姓名 5F20与持卡人姓名扩展9F0B只能使用一个&#xff0c;另一个必须不…

BindingException: Parameter 'XXX' not found. Available parameters are [collection, list]

应业务需求&#xff0c;需要使用到MQ进行数据上传和下发。传递格式为JSON,服务那边下发JSON数组&#xff0c;接收端将JSON数组转换成List集合&#xff0c;调用Mybatis-plus批量添加saveBatch()。提示字段未找到... org.apache.ibatis.exceptions.PersistenceException: ### Er…

JDK 8 新特性 之 default关键字

前言 Jdk1.8之前的接口中只声明方法&#xff0c;方法具体实现应在子类中进行。Jdk1.8打破了这样的用法&#xff1a;接口中可以实现具体的方法体&#xff0c;只需要加上关键字static或者default修饰即可。 default关键字 public interface UserService {//自定义方法void getUse…

headroom.js插件使用方法

1.什么是headroom.js&#xff1f; headroom是用纯Javascript写的插件&#xff0c;用来隐藏和展示页面元素&#xff0c;从而为页面留下更多空间。比如使用headroom能使导航栏当页面下滚时消失&#xff0c;当页面上滚时候又出现。&#xff08;查看效果&#xff09; 2.工作原理 通…

JDK 8 新特性 之 方法引用

概述 方法引用&#xff1a;当要传递给Lambda体的操作&#xff0c;已经有实现的方法了&#xff0c;就可以使用方法引用方法引用&#xff1a;在Lambda的基础上进一步的简化。换句话说&#xff0c;方法引用就是Lambda表达式&#xff0c;也就是函数式接口的一个实例&#xff0c;通过…

项目记录:springmvc forward redirect 问题

RequestMapping("/redirect")public String redirect(RedirectAttributes redirectAttributes){redirectAttributes.addFlashAttribute("test", "testdata"); //专供此种情况下使用。return "redirect:read";} 注意&#xff1a;此种情…

JDK 8 新特性 之 Lambda表达式

前言 Lambda 表达式&#xff0c;也可称为闭包&#xff0c;它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为参数传递进方法中。使用 Lambda 表达式可以使代码变的更加简洁紧凑。lambda表达式的重要特征: 可选类型声明&#xff1a;不需要声明参数类型&#xff0c;编译…

开源组件DocX导出Word

1、使用Docx替换Word模板里书签里内容的一个方法 using Novacode;public class ExportWord{/// <summary>/// 导出word/// </summary>/// <param name"lBookMarks">书签数据源</param>/// <param name"sTemplatePath">导出W…

JDK 8 新特性 之 Strams简单使用

概述 Java 8 API添加了一个新的抽象称为流Stream&#xff0c;可以让你以一种声明的方式处理数据。 Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。 Stream API可以极大提供Java程序员的生产力&#xff0c;让程序员写出…

Cannot open include file: jni.h: No such file or directory解决方法

在此运行Visual Studio 2012 项目时出现 #include <stdio.h> #include <jni.h> int main() { printf("Hello World"); } But when I try to build, I get the following error - 1>c:testtest.cpp(2) : fatal error C1083: Cannot open include file:…

JDK 8 新特性 之 函数接口

函数接口 定义:接口中只有唯一的一个抽象方法&#xff0c;该接口就称之为函数接口。 //函数接口 public interface FunctionInterface1 {//1、只有一个方法的接口&#xff0c;默认称之为函数接口void get(); }//非函数接口 public interface FunctionInterface2 {void get1();v…

微服务之基础知识

什么是微服务架构 微服务是系统架构上的一种设计风格&#xff0c; 它的主旨是将一个原本独立的系统拆分成多个小型服务&#xff0c;这些小型服务都在各自独立的进程中运行&#xff0c;服务之间通过基于HTTP的RESTful API进行通信协作。 被拆分成的每一个小型服务都围绕着系统中…

LightOj 1078 Basic Math

思路&#xff1a; 设输入的两个数分别为n和a,每一次所得到的数为update&#xff1a; 开始updatea,依次update分别为update*10a,这样数据会超出范围&#xff0c;则update每次为update(update*10a)%n即可&#xff0c; 如果update0,跳出循环&#xff1b; 只需证明&#xff1a;(upd…