trie树讲解

如果可以,可以陪你千年不老,千年只想眷顾你倾城一笑;如果愿意,愿意陪你永世不离,永世只愿留恋你青丝白衣。

首先什么是trie树呢?

Trie树也叫字典树,是一种树形结构,专门用于处理在一个字符串集合中查找某个字符串。

那trie树在我们实际应用中有哪些例子呢?

其实trie树这种数据结构,应用十分常见,比如所我们的搜索引擎就是利用了这一个功能,要知道数据库是十分庞大的,从里面查找一个内容效率并不是很高,而利用trie树这一结构可以很快地通过关键词查到,而且还会出现一系列相关的词条。

平常使用的百度搜索:

淘宝购物:

trie在算法上有什么作用呢?

(1)查询某个字符串是否出现过

(2)查询某个前缀是否出现过

(3)查询某个单词出现过几次或者某个前缀出现过几次(你只需要在建树的时候用book数组记录一下出现次数就可以了)。

说了那么多那trie树到底长什么样儿呢?

例如:需要在how,him,hi,hello,so,see这六个字符串中查找某个字符串,那我们就可以建个下面的trie树:

那这样就行了吗?比如我们要查询hi,会发现him的前缀中也包含hi,所以我们要在每一个字符串的结尾加入一个结束符。

构造过程也是将字符桉树连接起来就行,上面的图中很明显有一个不包含任何信息的根节点。

所以,利用代码实现是怎样的呢?

实现查询某个字符串是否出现过

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <ctime>
#include <cctype>
#include <bitset>
#include <utility>
#include <sstream>
#include <complex>
#include <iomanip>
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int maxn=1e3;
int trie[maxn][maxn],book[maxn];
int tot=0;
void init()
{
    memset(trie,0,sizeof(trie));
    memset(book,0,sizeof(book));
    tot=0;
}
void build(string s)
{
    int u=0;
    for(int i=0; i<s.size(); i++)
    {
        int c=s[i]-'a';
        if(trie[u][c]==0)
            trie[u][c]=++tot;
        u=trie[u][c];
    }
    book[u]=1;
}
int query(string s)
{
    int len=s.size();

    int u=0;
    for(int i=0; i<len; i++)
    {
        if(trie[u][s[i]-'a']==0)
            return 0;
        u=trie[u][s[i]-'a'];
    }
    if(book[u])
        return 1;
}
int main()
{
    int n;
    string s;
    init();
    cin>>n;
    getchar();
    while(n--)
    {
        cin>>s;
        build(s);
    }
    cin>>s;
    cout<<query(s)<<endl;
    return 0;
}

实现查询某个前缀是否出现过

int query(string s)
{
	int len=s.size();

	int u=0;
	for(int i=0;i<len;i++)
	{
		if(trie[u][s[i]-'a']==0)
		{
			return 0;
		}

		u=trie[u][s[i]-'a'];
	}
	return 1;
}

 

那trie树的缺点是什么呢?

trie树虽然节省了时间,但是却是消耗了空间,是用空间换时间的一种数据结构。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值