trie数和后缀树

1.trie树

字典树(trie)可以保存一些字符串->值的对应关系,字典树的插入和查询时间复杂度都是O(k),其中k是key的长度,与字典树中保存元素数无关。其缺点是空间消耗高。

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

trie树的结点信息结构体:

struct TrieNode{
	int count;     //统计该结点的单词出现的次数
	bool exist;    //标记该结点是否构成单词
	TrieNode *next[26];  //指针数组,数组的元素的类型是TrieNode*
};

trie树的插入和查找:

#include <iostream>
using namespace std;

struct TrieNode{
	int count;     //统计该结点的单词出现的次数
	bool exist;    //标记该结点是否构成单词
	TrieNode *next[26];  //指针数组,数组的元素的类型是TrieNode*
};


/*创建一个结点*/
TrieNode *CreateTrieNode()
{
	TrieNode *node = new TrieNode();
	node->count = 0;
	node->exist = 0;  //该结点不构成单词
	memset(node->next, 0, sizeof(node->next));  //将next指向的连续区域初始化为空
	return node;
}

/*往trie树里插入单词*/
void TrieInsert(TrieNode *root, char *word)
{
	if (word == NULL) return;
	TrieNode *node = root;
	char *str = word;
	int id;
	while (*str)
	{
		id = *str - 'a';
		if (node->next[id] == NULL)
		{
			node->next[id] = CreateTrieNode();
		}
		node = node->next[id];
		//node->count++;     //如果要统计以某个字符串为前缀的数量,在次数加
		++str;
	}
	node->exist = true;   //构成单词
	node->count++;        //如果要统计某个单词出现的次数,在次数加
}


/*查找某一个单词出现次数*/
int TrieSearch(TrieNode *root, char *word)
{
	if (word == NULL) return 0;
	TrieNode *node = root;
	char *str = word;
	int id;
	while (*str)
	{
		id = *str - 'a';
		node = node->next[id];
		if (node == NULL) return 0;
		++str;
	}
	return node->count;
}


int main(void)
{
	TrieNode *root = CreateTrieNode();     // 初始化字典树的根节点  
	char str[12];
	bool flag = false;
	while (gets_s(str,12))
	{
		if (flag)
			printf("%d\n", TrieSearch(root, str));
		else
		{
			if (strlen(str) != 0)
			{
				TrieInsert(root, str);
			}
			else
				flag = true;
		}
	}
	return 0;
}

参考:http://blog.csdn.net/hackbuteer1/article/details/7964147

2.后缀树
后缀树就是一颗压缩后的Trie,存储了字符串的所有后缀。

    原文作者:Trie树
    原文地址: https://blog.csdn.net/tianya_team/article/details/50838685
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞