字典樹又稱單詞查詢樹,trie樹,是一種樹形結構,是一種雜湊樹的變種。典型應用是用於統計,排序和儲存大量的字串(但不僅限於字串),所以經常被搜尋引擎系統用於文字詞頻統計。它的優點是:利用字串的公共字首來減少查詢時間,最大限度地減少無謂的字串比較,查詢效率比雜湊樹高。
常見的可以使用字典樹解決的問題舉例:
1、已知n個單詞,對於每乙個單詞,判斷它有沒有出現過,如果出現了,求第一次出現在第幾個位置。
2、已知n個由小寫字母構成的平均長度為10的單詞,判斷其中是否存在某個串為另乙個串的字首子串。
3、有乙個1g大小的乙個檔案,裡面每一行是乙個詞,詞的大小不超過16位元組,記憶體限制大小是1m,返回頻數最高的100個詞。
4、1000萬字串,其中有些是重複的,需要把重複的全部去掉,保留沒有重複的字串。
5、乙個文字檔案,大約有一萬行,每行乙個詞,要求統計出其中最頻繁出現的前10個詞。
6、給定n個互不相同的僅由乙個單詞構成的英文名,讓你將他們按字典序從小到大輸出。
上面的問題都可以通過建乙個字典樹解決,將字串分別插入到字典樹中,插入的同時可以進行查詢,這樣就可以知道該字串有沒有出現過。字典樹結點可以新增一些附加資訊,比如該結點代表的字元出現的次數,該結點是不是某個字串的結尾以及該字串出現的次數等。另外,對字典樹進行先序遍歷可以輸出字串的排序。
tire樹的結構如下圖所示:
每個節點代表乙個字元,從根節點向下遍歷可以得到所有字串的字首,遇到結尾字元(紅色)就得到乙個字串。
下面是我寫的字典樹簡單實現,該字典樹不僅儲存了每個字元出現的次數(成員變數_count),該字典樹中字串的出現次數(成員變數_isend)。在插入字串的每個字元的時候需要更新_count,插入完乙個字串後更新_isend。最後,刪除乙個字串需要注意的是先判斷是否存在待刪除的字串,如果存在,那麼應該從下而上判斷和刪除節點(如果節點的計數為1,那麼就釋放記憶體,否則減小_count)。
/*實現乙個字典樹*/
#include #include #include struct trienode
; int _isend;//表示字串的結尾,_isend可以表示字元出現次數
int _count;//字元出現的次數
tirenode* children[max];//指標陣列
tirenode() : _isend(0), _count(1) };
trienode* create()
void insert(trienode* root, const char* str)
trienode* p = root;
while (*str != '\0')
else
p = p->children[*str - 'a'];
++str;
} p->_isend++;//插完乙個字串更新其出現的次數
}//字典樹root是否包含字串str, 如果isprefix == true,那麼str是root中某個字串的乙個字首
bool contains(trienode* root, const char* str, bool& isprefix)
if ('\0' == *str)
trienode* p = root;
while (p != null && *str != '\0')
//當*str == '\0'的時候,p指向str的最後乙個有效字元(不是'\0')
isprefix = false;
if (p != null) }
return false;
}//從字典樹中刪除字串str,如果不存在就返回false,成功刪除就返回true
bool remove(trienode* root, const char* str)
if ('\0' == *str)
std::stacks;//結點只能從下向上刪除,否則會破壞樹結構,釋放記憶體後要置null,故儲存指標的位址!!!
trienode* p = root;
while (p != null && *str != '\0')
p = p->children[*str - 'a'];
++str;//str跳到下乙個字元 }
if (p != null && p->_isend > 0) //存在字串str
else
s.pop();
} }return false;//trie樹中不存在str
}void release(trienode* root)
} delete root;
}
Trie樹(字典樹)的實現
trie樹,即字典樹,又稱單詞查詢樹或鍵樹,是一種樹形結構,是一種雜湊樹的變種。典型應用是用於統計和排序大量的字串 但不僅限於字串 所以經常被搜尋引擎系統用於文字詞頻統計。它的優點是 最大限度地減少無謂的字串比較,查詢效率比雜湊表高。trie的核心思想是空間換時間。利用字串的公共字首來降低查詢時間的...
trie樹 字典樹 java實現
public class trie public void insert string word else current.count current.isend true 怎麼判斷單詞是否存在?被判斷的單詞的字母與根節點下的子節點的字母進行比較,直到匹配到兩者最後乙個字母相同,並且最後乙個節點的i...
Trie字典樹陣列實現
include using namespace std const int n 10010 int son n 26 儲存下乙個字元的行 int count n 這個單詞單詞有多少個 int pos 當前新分配的儲存位置 char szstr n 讀取字串 void stringinsert con...