这个高级数据结构系列我会写三中在编程里常见的三种数据机构,分别是Trie 树,并查集和线段树。
trie树(字典树)的基础知识
trie树,又称字典树或前缀树,是一种有序的、用于统计、排序和存储字符串的数据结构,它与二叉查找树不同,关键字不是直接保存在节点中,而是由节点在树中的位置决定。 一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。 trie树的最大优点就是利用字符串的公共前缀来减少存储空间与查询时间,从而最大限度地减少无谓的字符串比较,是非常高效的字符串查找数据结构。
首先定义基本的数据结构:
class TrieNode
{
bool IsEnd;//是否为一个单词的结尾
TrieNode* childnodes[26];
TrieNode(): IsEnd(false)
{
for(int i = 0;i < MAX;i++)
{
childNode = nullptr;
}
}
};
Trie树的基本功能实现:
class Trie {
private:
std::vector<TrieNode*> _node_vec;
//用来存储new出来的结点,这样在析构的时候可以释放内存;
TrieNode* new_node()
{
TrieNode* node = new TrieNode();
_node_vec.push_back(node);
return node;
}
public:
TrieNode* root;
public:
Trie() {
root = new TrieNode();
}
~Trie()
{
for(int i =0;i<_node_vec.size();i++)
{
delete _node_vec[i];
}
}
// Inserts a word into the trie.
void insert(string word) {
}
// Returns if the word is in the trie.
bool search(string word) {
}
// Returns if there is any word in the trie
// that starts with the given prefix.
bool startsWith(string prefix) {
}
};
//获取trie树的所有单词
void get_all_word_from_trie(TrieNode*root,string &word,vector<string> &word_list)
{
}
插入:
void insert(string word) {
TrieNode * p=root;
int length = word.length();
for(int i =0;i<length;i++)
{
if(!p->child[word[i]-'a'])
{
p->child[word[i]]=new TrieNode();
}
p=p->child[word[i]];
}
p->isEnd=true;
}
查找:
bool search(string word) {
int lenth = word.length();
TrieNode *p = root;
for(int i = 0;i<lenth;i++)
{
int index = word[i]-'a';
if(!p->next[index])
{
return false;
}
else
{
p = p->next[index];
}
}
if(p->IsLeave) return true;
else return false;
}
前缀:
bool startsWith(string prefix) {
int lenth = prefix.length();
TrieNode *p = root;
for(int i = 0;i<lenth;i++)
{
int index = prefix[i]-'a';
if(!p->next[index])
{
return false;
}
else
{
p = p->next[index];
}
}
return true;
}
查找Tire树中所有的单词:
void get_all_word_from_trie(TrieNode*root,string &word,vector<string> &word_list)
{//word是保存字符串的栈,
if(!root)
return;
for(int i =0;i<Max;i++)
{
if(root->next[i])
{
word.push_back('a'+i);
if(root->next[i]->IsLeave)
word_list.push_back(word);
//深度遍历
get_all_word_from_trie(root->next[i],word,word_list);
word.erase(word.length()-1,1);//弹出栈顶字符
}
}
}
完整代码可以戳➡️我的GitHub:还有Trie树的模版实现方式哦~
希望大家一起进步~