前綴樹

#defin trie_n trie_n

套用

Trie樹常用於搜尋提示。如當輸入一個網址,可以自動搜尋出可能的選擇。當沒有完全匹配的搜尋結果,可以返回前綴最相似的可能。

實現

trie樹實際上是一個DFA,通常用轉移矩陣表示。行表示狀態,列表示輸入字元,(行, 列)位置表示轉移狀態。這種方式的查詢效率很高,但由於稀疏的現象嚴重,空間利用效率很低。也可以採用壓縮的存儲方式即鍊表來表示狀態轉移,但由於要線性查詢,會造成效率低下。
於是人們提出了下面兩種結構。

三數組Trie

三數組Trie(Tripple-Array Trie)結構包括三個數組:base,next和check.

二數組Trie

二數組Trie(Double-Array Trie)包含base和check兩個數組。base數組的每個元素表示一個Trie節點,即一個狀態;check數組表示某個狀態的前驅狀態。

實例

這是一個用於詞頻統計的程式範例,因使用了GetLine(3),所以需要glibc才能連結成功,沒有glibc的話可以自行改寫。代碼由“JohnBull”捐獻,遵從GPL著作權聲明。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TREE_WIDTH 256
#define WORDLENMAX 128
struct trie_node_st {
int count;
struct trie_node_st *next[TREE_WIDTH];
};
static struct trie_node_st root={0, {NULL}};
static char *spaces=" \t\n/.\"\'()";
static int
insert(const char *word)
{
int i;
struct trie_node_st *curr, *newnode;
if (word[0]=="\0") {
return 0;
}
curr = &root;
for (i=0; ; ++i) {
if (word[i] == '\0') {
break;
}
if (curr->next[ word[i] ] == NULL) {
newnode=(struct trie_node_st*)malloc(sizeof(struct trie_node_st));
memset(newnode, 0, sizeof(struct trie_node_st));
curr->next[ word[i] ] = newnode;
}
curr = curr->next[ word[i] ];
}
curr->count ++;
return 0;
}
static void
printword(const char *str, int n)
{
printf("%s\t%d\n", str, n);
}
static int
do_travel(struct trie_node_st *rootp)
{
static char worddump[WORDLENMAX+1];
static int pos=0;
int i;
if (rootp == NULL) {
return 0;
}
if (rootp->count) {
worddump[pos]="\0";
printword(worddump, rootp->count);
}
for (i=0;i<TREE_WIDTH;++i) {
worddump[pos++]=i;
do_travel(rootp->next[i]);
pos--;
}
return 0;
}
int
main(void)
{
char *linebuf=NULL, *line, *word;
size_t bufsize=0;
int ret;
while (1) {
ret=getline(&linebuf, &bufsize, stdin);
if (ret==-1) {
break;
}
line=linebuf;
while (1) {
word = strsep(&line, spaces);
if (word==NULL) {
break;
}
if (word[0]=="\0") {
continue;
}
insert(word);
}
}
/* free(linebuf); */
do_travel(&root);
exit(0);
}

相關詞條

相關搜尋

熱門詞條

聯絡我們