思维导图
前缀树的核心思想是利用字符串的前缀去匹配字符串,可以不用去管那些和前缀不符的字符串,例:
已有["hello" , "world" ,"happy "]
我们需要检索是否已存入hello
此时的Trie为
匹配hellow时,从hellow的第一个前缀往后匹配
现在我们来看下前缀树的c++实现代码
#include<iostream>
using namespace std;
const int L = 26;//模拟26个字母
class Trie
{
private :
Trie* children[L];//数组下标表示 所装的字母 如 0 表示 a, 1 表示 b
Trie* father;//方便删除时回溯
bool isend;//若为true 表示已存入的单词中有以该字母结尾的
public :
Trie()
{
for(int i = 0; i < L; i++)//利用构造函数 初始化成员
{
children[i] = nullptr;
father = nullptr;
isend = false;
}
}
void insert(string word)//插入函数
{
Trie* p = this;
Trie* r;
int site;
for(auto ch : word)
{
site = ch - 'a';//将字符转为数组下标
r = p;
if(p->children[site] == nullptr) p->children[site] = new Trie();//若为添加过此前缀 添加该前缀
p = p->children[site];//操作下一前缀
p->father = r;
}
p->isend = true;//插入单词结束 给末尾字符加上标记
}
bool search(string word)//查找函数 查找一个单词是否存在于字典树中
{
Trie* p = this;
int site;
for(auto ch : word)
{
site = ch - 'a';//将字符转为数组下标
if(p->children[site] == nullptr) return false;
p = p->children[site];//操作下一前缀
}
if(p->isend) return true;//匹配的前缀为一个单词
return false;//虽然该字符已匹配 但之前插入的单词只是以该字符串作为前缀 并不作为一个单词
}
bool start_with(string word)// 查找字典树中是否有 以目标串作为前缀的单词
{
Trie* p = this;
int site;
for(auto ch : word)
{
site = ch - 'a';//将字符转为数组下标
if(p->children[site] == nullptr) return false;
p = p->children[site];//操作下一前缀
}
return true;//字符串匹配完成 返回true
}
void delete_word(string word)//删除函数
{
Trie* p = this;
if(!p->search(word)) return;//该单词不存在,不需要删除
int site;
Trie* r;
for(auto ch : word)
{
site = ch - 'a';
p = p->children[site];
}//找到最後一個字符的位置
int flag = 0;//标记是否有单词以删除字符串为前缀 0 为没有
for(auto q : p->children)
{
if(q != nullptr)
{
flag = 1;
break;
}
}
if(flag) p->isend =false;//若有单词以此为前缀 不需要删除字符串 擦除结尾标记即可
else
{
r = p->father;
while(r != nullptr)
{
for(int i = 0; i < 26; i++)
{
if(r->children[i] == p) r->children[i] = nullptr;
else if(r->children[i] != nullptr)
{
flag = 1;
break;
}
}
if(flag) return;
p = r;
r = r->father;
}
}
}
};
int main()
{
Trie* p = new Trie();//实例化 对象
p->insert("hellow");
cout<<p->search("hellow")<<endl;
cout<<p->search("happy")<<endl;
p->insert("happy");
cout<<p->search("happy")<<endl;
cout<<p->start_with("ha")<<endl;
p->delete_word("happy");
cout<<p->search("happy");
return 0;
}
后续我还会加上c语言代码