數據結構——前綴樹
阿新 • • 發佈:2019-02-05
php stl null ring 多少 problem urn alloc include
Trie(前綴樹/字典樹)
Trie,又經常叫前綴樹,字典樹等等,是一種多叉樹結構。如下圖:
基本功能實現:
只記錄小寫字母,用pass記錄有多少字符串經過該節點,end記錄有多少字符串以該節點結尾。
- 用數組實現:
#include <iostream> #include <malloc.h> #include <string> using namespace std; typedef struct node{ int pass; int end; struct node* next[26]; } *trieTree; trieTree init() { trieTree t= (trieTree)malloc(sizeof(node)); for (int i = 0; i < 26; i++) t->next[i] = NULL; for (int i = 0; i < 26; i++) t->next[i] = NULL; t->pass = 0; t->end = 0; return t; } void insert(trieTree T,string s) { node *n = T; for (int i = 0; i < s.length(); i++) {int index = s[i] - ‘a‘; if (T->next[index] == NULL) { node *t = init(); T->next[index] = t; } T = T->next[index]; T->pass++; } T->end++; } int find(trieTree T, string s) { node *n = T; for (int i = 0; i < s.length(); i++) {int index = s[i] - ‘a‘; if (T->next[index] == NULL) { return NULL; } T = T->next[index]; } return T->pass; }
- 用STL map實現:
#include <iostream> #include <map> #include <string> using namespace std; class node{ public: int pass; int end; map<char,struct node *>m; }; typedef node* trieTree; trieTree init() { trieTree t = new node; //別的很多人可能初始值給的是1,仔細看insert的代碼,這裏是沒錯的 t->pass = 0; t->end = 0; return t; } void insert(trieTree T,string s) { for (int i = 0; i < s.length(); i++) { if (T->m.find(s[i]) == T->m.end()) { node *t = init(); T->m.insert(make_pair(s[i], t)); } T = T->m[s[i]]; T->pass++; } T->end++; } int find(trieTree T, string s) { node *n = T; for (int i = 0; i < s.length(); i++) { if (T->m.find(s[i]) == T->m.end()) { return NULL; } T = T->m[s[i]]; } return T->pass; }
應用:
前綴樹典型應用是用於統計,排序和保存大量的字符串,所以經常被搜索引擎系統用於文本詞頻統計。
它的優點是:利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較。
具體應用主要分為四類:
- 前綴匹配 :HDU 1251:隨手練——HDU 1251 統計難題
- 字符串檢索 :
- 詞頻統計 :當使用map內存不夠時。
- 字符串排序:Trie樹是一棵多叉樹,只要先序遍歷整棵樹,輸出相應的字符串便是按字典序排序的結果。
比如給你N 個互不相同的僅由一個單詞構成的英文名,讓你將它們按字典序從小到大排序輸出。
數據結構——前綴樹