前言
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
性质
- 根节点不包含字符,除根节点外每一个节点都只包含一个字符;
- 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串;
- 每个节点的所有子节点包含的字符都不相同。
实现方法
搜索字典项目的方法为:
1. 从根结点开始一次搜索;
2. 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;
3. 在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索。
4. 迭代过程……
5. 在某个结点处,关键词的所有字母已被取出,则读取附在该结点上的信息,即完成查找。
6. 其他操作类似处理
案例
此案例主要作用为先输入一个数字表示接下来要输入多少行字符串(10字节内)插入Trie树中。再输入一个数字表示接下来要查询的字符串或前缀。此案例会返回查询的包含该前缀的字符串个数。
编写环境:vs2013
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
#define MAXCHILD 26
int wordCount = 0;
typedef struct _TrieNode
{
int flag;
struct _TrieNode* ChildNode[MAXCHILD];
}TrieNode;
// 初始化
TrieNode* CreatTrie()
{
TrieNode* tree = (TrieNode*)malloc(sizeof(TrieNode));
memset(tree, 0, sizeof(TrieNode));
return tree;
}
// 插入
int InsertTrie(char* str, TrieNode* root)
{
if (root == NULL || *str == '\0')
return -1;
char* p = str;
TrieNode* tmp = root;
while (*p != '\0')
{
if ((tmp->ChildNode[*p - 'a']) == NULL)
{
TrieNode* data = CreatTrie();
tmp->ChildNode[*p - 'a'] = data;
}
tmp = tmp->ChildNode[*p - 'a'];
p++;
}
tmp->flag = 1;
}
void CountWord(TrieNode* root)
{
int i = 0;
TrieNode* tmp = root;
for (i = 0; i < MAXCHILD; ++i)
{
if (tmp->ChildNode[i] != NULL)
{
if (tmp->flag == 0)
{
tmp = tmp->ChildNode[i];
CountWord(tmp);
}
if (tmp->flag != 0)
wordCount++;
}
}
}
// 查找
int FindTrie(char* str, TrieNode* root)
{
if (root == NULL || *str == '\0')
return -1;
char* p = str;
TrieNode* tmp = root;
while (*p != '\0')
{
if (tmp->ChildNode[*p - 'a'] == NULL)
return 0;
else
{
tmp = tmp->ChildNode[*p - 'a'];
p++;
}
}
CountWord(tmp);
}
// 释放
void DelTrie(TrieNode* root)
{
int i;
for (i = 0; i<MAXCHILD; i++)
{
if (root->ChildNode[i] != NULL)
DelTrie(root->ChildNode[i]);
}
free(root);
}
int main()
{
TrieNode* root = NULL;
root = CreatTrie();
if (root == NULL)
{
printf("creatTrie err\n");
return -1;
}
int count = 0;
scanf("%d", &count);
getchar();
char buf[11];
while (count--)
{
scanf("%s", buf);
InsertTrie(buf, root);
}
printf("------------\n");
scanf("%d", &count);
while (count--)
{
scanf("%s", buf);
FindTrie(buf, root);
printf("%d\n", wordCount);
wordCount = 0;
}
DelTrie(root);
system("pause");
return 0;
}