字典树/trie树,基数树/radix树

转自:百度百科:http://baike.baidu.com/view/2759664.htm

参考:开源世界中的算法与数据结构 3 – Linux IPv6 FIB表实现

参考:基数(radix)树 

字典树又称单词查找树,Trie树;所谓PATRICIA Tree或Radix Tree(基数树)是同一种数据结构, 不是标准Trie树,是Trie树的优化变异。

优点:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。

1、Trie树性质:

Trie树有3个基本性质:

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

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

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

Trie树和radix树分别如下图:

《字典树/trie树,基数树/radix树》《字典树/trie树,基数树/radix树》

2、Trie树应用:

a. 串的快速检索:
给出N个单词组成的熟词表,以及一篇全用小写英文书写的文章,请你按最早出现的顺序写出所有不在熟词表中的生词。
在这道题中,我们可以用数组枚举,用哈希,用字典树,先把熟词建一棵树,然后读入文章进行比较,这种方法效率是比较高的。

b. “串”排序:
给定N个互不相同的仅由一个单词构成的英文名,让你将他们按字典序从小到大输出。
用字典树进行排序,采用数组的方式创建字典树,这棵树的每个结点的所有儿子很显然地按照其字母大小排序。对这棵树进行先序遍历即可。

c. 最长公共前缀
对所有串建立字典树,对于两个串的最长公共前缀的长度即他们所在的结点的公共祖先个数,于是,问题就转化为当时公共祖先问题(以后补上)。

3、一个radix树应用:

一个3级结点的radix树及其键值表示:

Linux radix树每个结点有64个slot(每一个slot存放一个指针,指向子节点或item),与数据类型long的位数相同,图1显示了一个有3级结点的radix树,每个数据条目(item)可用3个6位的键值(key)进行索引,键值从左到右分别代表第1~3层结点位置。没有孩子的结点在图中不出现。因此,radix树为稀疏树提供了有效的存储,代替固定尺寸数组提供了键值到指针的快速查找。

《字典树/trie树,基数树/radix树》

4、Trie树一个简单的实现

#define MAX 26//字符集大小
typedef struct TrieNode
{
int nCount;//记录该字符出现次数
struct TrieNode* next[MAX];
}TrieNode;
 
TrieNode Memory[1000000];
int allocp=0;
 
/*初始化*/
void InitTrieRoot(TrieNode** pRoot)
{
*pRoot=NULL;
}
 
/*创建新结点*/
TrieNode*CreateTrieNode()
{
inti;
TrieNode* p;
p=&Memory[allocp++];
p->nCount=1;
for(i=0;i<MAX;i++)
{
p->next[i]=NULL;
}
return p;
}
 
/*插入*/
void InsertTrie(TrieNode** pRoot,char* s)
{
int i,k;
TrieNode* p;
if(!(p=*pRoot))
{
p=*pRoot=CreateTrieNode();
}
i=0;
while(s[i])
{
k=s[i++]-'a';//确定branch
if(p->next[k])
p->next[k]->nCount++;
else
p->next[k]=CreateTrieNode();
p=p->next[k];
}
}
 
//查找
intSearchTrie(TrieNode** pRoot,char* s)
{
TrieNode *p;
inti,k;
if(!(p==*pRoot))
{
return 0;
}
i=0;
while(s[i])
{
k=s[i++]-'a';
if(p->next[k]==NULL) return 0;
p=p->next[k];
}
return p->nCount;
}

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