1. 程式人生 > >字典樹(原創)

字典樹(原創)

() 公共前綴 tdi 排序。 color 所在 lag 優點 logo

1.概念

1.又稱單詞查找樹,Trie樹,是一種樹形結構,是一種哈希樹的變種。典型應用是用於統計,排序和保存大量的字符(但不僅限於字符串),所以經常被搜索引擎系統用於文本詞頻統計。

2.優點:

利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較,查詢效率比哈希樹高。

3.基本性質: a.根節點不包含任何字符,除根節點外每一個節點都只包含一個字符; b.從根節點到某一節點,路徑上經過的字符連接起來,為該節點對應的字符串; 每個節點的所有子節點包含的字符都不相同。 c.字典樹的節點並不真正存儲該字符。 4.功能: a.查找某單詞 b.統計某單詞出現的次數 c.對單詞進行排序 d.刪除(比較少用) 5.應用:
1.串的快速檢索 給出N個單詞組成的熟詞表,以及一篇全用小寫英文書寫的文章,請你按最早出現的順序寫出所有不在熟詞表中的生詞。 在這道題中,我們可以用數組枚舉,用哈希,用字典樹,先把熟詞建一棵樹,然後讀入文章進行比較,這種方法效率是比較高的。 2.“串”排序 給定N個互不相同的僅由一個單詞構成的英文名,讓你將他們按字典序小到大輸出 用字典樹進行排序,采用數組的方式創建字典樹,這棵樹的每個結點的所有兒子很顯然地按照其字母大小排序。對這棵樹進行先序遍歷即可。

3.最長公共前綴

對所有串建立字典樹,對於兩個串的最長公共前綴的長度即他們所在的結點的公共祖先個數,於是,問題就轉化為當時公共祖先問題。 6.實現分析:
本文以都是小寫字母為例,即該樹有26個叉(後期豐富可以加上大寫字母,規定字符等) 每一個節點都含有一個指針數組,每個指針數組裏裝26根指針,除了該指針數組之外,每個節點還應該有一個標誌flag。 flag有以下作用: a.初始為0,當當前節點是某個單詞結尾的時候,flag加一, b.同時flag也可以用來統計單詞數
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 
  5 typedef struct node
  6 {
  7     int nFlag;
8 struct node *pCharacter[26]; 9 char *str;//若某節點是某個單詞的結尾,則把該單詞保存在該節點中。 10 }TrieTree; 11 12 void AddWord(TrieTree *pTree,char *str) 13 { 14 int i; 15 TrieTree *pTemp = NULL; 16 for(i = 0;i<strlen(str);i++) 17 { 18 //節點的對應位置空 添加節點 19 if(pTree->pCharacter[str[i]-97] == NULL) 20 { 21 pTemp = (TrieTree*)malloc(sizeof(TrieTree)); 22 memset(pTemp,0,sizeof(TrieTree)); 23 24 pTree->pCharacter[str[i]-97] = pTemp; 25 } 26 27 //向下走 28 pTree = pTree->pCharacter[str[i]-97]; 29 } 30 31 //末尾標記 32 pTree->nFlag++; 33 pTree->str = str; 34 } 35 36 37 TrieTree *CreateTrieTree(char *str[],int nLength) 38 { 39 if(str == NULL || nLength <=0)return NULL; 40 41 TrieTree *pRoot = NULL; 42 pRoot = (TrieTree*)malloc(sizeof(TrieTree)); 43 memset(pRoot,0,sizeof(TrieTree)); 44 45 //將字符串依次添加 46 int i; 47 for(i = 0;i<nLength;i++) 48 { 49 AddWord(pRoot,str[i]); 50 } 51 return pRoot; 52 } 53 54 void Search(TrieTree *pRoot,char *str) 55 { 56 if(str == NULL || pRoot == NULL)return; 57 58 int i; 59 for(i = 0;i<strlen(str);i++) 60 { 61 if(pRoot->pCharacter[str[i]-97] == NULL) 62 { 63 printf("failed.\n"); 64 return; 65 } 66 pRoot = pRoot->pCharacter[str[i]-97]; 67 } 68 69 //檢測末尾標誌 70 if(pRoot->nFlag != 0 ) 71 { 72 printf("%s\n",pRoot->str); 73 return; 74 } 75 else 76 { 77 printf("hhhh failed.\n"); 78 return; 79 } 80 } 81 82 void Traversal(TrieTree *pTree) 83 { 84 if(pTree == NULL) 85 return; 86 87 if(pTree->nFlag != 0) 88 { 89 printf("%s\n",pTree->str); 90 } 91 92 int i; 93 for(i = 0;i<26;i++) 94 { 95 Traversal(pTree->pCharacter[i]); 96 } 97 } 98 99 int main() 100 { 101 char *str[] = {"app","apple","orange","lemon","logo","ball","tie","glory"}; 102 TrieTree *pRoot = CreateTrieTree(str,8); 103 Traversal(pRoot); 104 printf("----------------------\n"); 105 Search(pRoot,"ball"); 106 return 0; 107 }

字典樹(原創)