trie樹常用於搜尋提示。如當輸入一個網址,可以自動搜尋出可能的選擇。當沒有完全匹配的搜尋結果,可以返回前綴最相似的可能。
實現,三數組Trie,二數組Trie,實例,
實現
trie樹實際上是一個DFA,通常用轉移矩陣表示。行表示狀態,列表示輸入字元,(行, 列)位置表示轉移狀態。這種方式的查詢效率很高,但由於稀疏的現象嚴重,空間利用效率很低。也可以採用壓縮的存儲方式即鍊表來表示狀態轉移,但由於要線性查詢,會造成效率低下。
於是人們提出了下面兩種結構。
三數組Trie
三數組Trie(Tripple-Array Trie)結構包括三個數組:base,next和check.
二數組Trie
二數組Trie(Double-Array Trie)包含base和check兩個數組。base數組的每個元素表示一個Trie節點,即一個狀態;check數組表示某個狀態的前驅狀態。
實例
#include <stdio.h>#include <stdlib.h>#include <string.h>#define TREE_WIDTH 256#define WORDLENMAX 128struct 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);}