您的位置:首页 > 其它

【hiho1014 Trie树】

2017-10-31 09:25 246 查看
Trie树,又称字典树

Trie树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。

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

Trie树的基本性质可以归纳为:

(1)根节点不包含字符,除根节点意外每个节点只包含一个字符。

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

(3)每个节点的所有子节点包含的字符串不相同。

Trie树有一些特性:

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

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

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

4)如果字符的种数为n,则每个结点的出度为n,这也是空间换时间的体现,浪费了很多的空间。

5)插入查找的复杂度为O(n),n为字符串长度。

基本思想(以字母树为例):

1、插入过程

对于一个单词,从根开始,沿着单词的各个字母所对应的树中的节点分支向下走,直到单词遍历完,将最后的节点标记为红色,表示该单词已插入Trie树。

2、查询过程

同样的,从根开始按照单词的字母顺序向下遍历trie树,一旦发现某个节点标记不存在或者单词遍历完成而最后的节点未标记为红色,则表示该单词不存在,若最后的节点标记为红色,表示该单词存在。



Trie树结构:

//Inter.h
struct Trie;
typedef struct Trie* node;
#define ALPHANUMBER 26
struct Trie
{
int count;
node son[ALPHANUMBER];

};
node createTrie();
void insertAlpha(node root,const char* str);
int numberOfPreorder(node root, const char* str);


建立树:

//Inter.c
node createTrie()
{
node it = (node)malloc(sizeof(struct Trie));
it->count = 1;
for (int i = 0; i < ALPHANUMBER; ++i)
{
it->son[i] = NULL;
}
return it;
}


插入:

//Inter.c
void insertAlpha(node root,const char* str)
{
if (str == NULL)
return;

node tmp = root;
int index;
while (*str != '\0')
{
index = *str - 'a';
if (tmp->son[index] != NULL)
{
tmp = tmp->son[index];
tmp->count += 1;
//边为字母,只有通过了这条边,才加1,这两句先后顺序很重要
}
else
{
tmp->son[index] = createTrie();
tmp = tmp->son[index];
}
++str;
}
}


查询:

//Inter.c

int numberOfPreorder(node root, const char* str)
{
if (str == NULL)
{
return 0;
}
node tmp = root;
int index;
while (*str != '\0')
{
index = *str - 'a';
if (tmp->son[index] == NULL)
{
return 0;
}
else
{
tmp = tmp->son[index];
}
++str;
}
return tmp->count;
}


Accept代码:(加上前面的Trie树定义)

//main.c
#include "Inter.h"
#include <iostream>
#include <stdlib.h>
#include <vector>
using namespace std;

int main()
{
node root = createTrie();
root->count = 0;

int n, m;
char alpha[11];
vector<int> res;
cin >> n;
while (n-- > 0)
{
cin >> alpha;
insertAlpha(root, alpha);
}
cin >> m;
while (m-- > 0)
{
cin >> alpha;
res.push_back(numberOfPreorder(root, alpha));
}
for (int i = 0; i < res.size(); ++i)
{
cout << res[i] << endl;
}
//system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: