trie树

来着wiki百科的介绍

trie,又称前缀树字典树,是一种有序,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。

trie树的查询速度,小于串长,所以速度很快,但空间代价很高(26^max(len))。与hash类似的情况。

主要用于快速查询,词频统计,前缀匹配,字符串排序(先序遍历,遇到为字符串输出)。

代码如下:

#include "vld.h"

#include <iostream>
#include <cassert>
#include <cctype>
using namespace std;


//申明使用必须为小写字母,否则出错!!
const int MAX_CHAR = 26;
typedef struct node
{
	int prefix_count;
	bool is_str;
	node *next[MAX_CHAR];
	node()
	{
		is_str = false;
		memset(next,NULL,sizeof(node*)*MAX_CHAR);
	}
}Trie;

void insert(node *root ,char* str)
{
	assert(root);
	node *p = root;

	for (int i = 0;str[i];i++)
	{
		assert(isalpha(str[i]));
		int index = tolower(str[i]) - 'a';
		if (p->next[index] == NULL)
		{
			p->next[index] = new node;
		}
		p->prefix_count ++;
		p = p->next[index];
	}
	p->is_str = true;
}

bool find(node *root ,char* str)//基本和插入类似都得遍历一边
{
	assert(root);
	node *p = root;

	for (int i = 0;str[i];i++)
	{
		assert(isalpha(str[i]));
		int index = tolower(str[i]) - 'a';
		if (p->next[index] == NULL)
		{
			return false;//此处!!
		}
		 
		p = p->next[index];
	}
  return p->is_str;//防止是中间的的前缀,而非完整的字符串(也可以直接返回真,表明找到前缀)
}

void delete_trie(node *root)
{
	for (int i = 0;i < MAX_CHAR;i++)//总共一个才删!!
	{
		if (root->next[i] != NULL)
		{
			delete_trie(root->next[i]);//回溯的方法删除!!
		}

	}
	delete root;	//技巧性很强!删除!!
}
int main()//必须保证只有字母!!
{
	char str[21];
	char ch;
	Trie *root = new Trie;
	do
	{
		cout<<"输入字符串(20内):"<<endl;
		cin>>str;
		insert(root,str);
		cout<<"继续?Y/N"<<endl;
		cin.get();//去换行	
		cin.get(ch);
		
	}while(ch != 'N'&&ch != 'n');
	
	cout<<"查找测试!"<<endl;
	do
	{
		cout<<"输入字符串(20内):"<<endl;
		cin>>str;
		if(find(root,str))
		{
			cout<<"找到!"<<endl;
		}
		else
		{
			cout<<"未找到!"<<endl;
		}
		cout<<"继续?Y/N"<<endl;
		cin.get();//去换行	
		cin.get(ch);
	
	}while(ch != 'N'&&ch != 'n');
	
	delete_trie(root);

	return 1;
}
//注要注意:对trie树的释放,并较好的的利用递归树。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值