#include<iostream>
#include<vector>
#include<algorithm>
#include<cctype>
using namespace std;
const int R = 26;
typedef struct TrieTree* Position;
enum Color{red,black};
struct TrieTree {
char ch;
Color color;
Position next[R];
};
class Trie {
public:
Trie();
~Trie();
void MakeEmpty(void);
vector<string>keys();
void Insert(string);
void Delete(string);
bool isempty();
bool Find(string) const;
vector<string>KeysWithPrefix(string)const;
private:
void MakeEmpty(Position);
void Insert(string, Position&, int);
void Delete(string, Position&, int);
Position Find(string, Position,int)const;
void Collect(string, Position, vector<string>&)const;
Position root;
};
Trie::Trie() {
root = new struct TrieTree;
if (root == NULL) {
cout << "申请失败"<<endl;
return;
}
else {
root->color = black;
for (int i = 0; i < R; i++) {
root->next[i] = NULL;
}
}
}
Trie::~Trie() {
MakeEmpty(root);
}
void Trie::MakeEmpty(void) {
for (int i = 0; i < R; i++) {
if (root->next[i] != NULL) {
MakeEmpty(root->next[i]);
}
}
}
void Trie::MakeEmpty(Position h) {
for (int i = 0; i < R; i++) {
if (h->next[i] != NULL) {
MakeEmpty(h->next[i]);
}
}
delete h;
h = NULL;
}
vector<string>Trie::keys() {
return KeysWithPrefix("");
}
void Trie::Insert(string key) {
Insert(key, root, 0);
}
void Trie::Insert(string key, Position& r, int k) {
if (r == NULL) {
r = new struct TrieTree;
if (r == NULL) {
cout << "申请失败" << endl;
return;
}
else {
r->color = black;
if (k - 1 >= 0) {
r->ch = key[k - 1];
}
for (int i = 0; i < R; i++) {
r->next[i] = NULL;
}
}
}
if (k == key.size()) {
r->color = red;
return;
}
int pos = tolower(key[k]) - 'a';
Insert(key, r->next[pos], k + 1);
}
void Trie::Delete(string key) {
Delete(key, root, 0);
}
void Trie::Delete(string key, Position& r, int k) {
if (r == NULL) {
return;
}
if (k == key.length()) {
r->color = black;
}
else {
int pos = tolower(key[k]) - 'a';
Delete(key, r->next[pos], k + 1);
}
if (r->color == red) {
return;
}
for (int i = 0; i < R; ++i) {
if (r->next[i] != NULL) return;
}
delete r;
r = NULL;
}
bool Trie::isempty() {
for (int i = 0; i < R; i++) {
if (root->next[i] != NULL) {
return false;
}
}
return true;
}
bool Trie::Find(string s)const {
Position p = Find(s, root, 0);
if (p == NULL) return false;
if (p->color == red) return true;
else return true;
}
Position Trie::Find(string s,Position r,int k) const{
if (r == NULL) {
return NULL;
}
if (k == s.size()) {
return r;
}
int pos = tolower(s[k]) - 'a';
return Find(s, r->next[pos], k + 1);
}
void Trie::Collect(string key, Position r, vector<string>& str)const {
if (r == NULL) {
return;
}
if (r->color == red) {
str.push_back(key);
}
for (int i = 0; i < R; i++) {
char ch = 'a' + i;
Collect(key + ch, r->next[i], str);
}
}
vector<string>Trie::KeysWithPrefix(string key)const {
vector<string>V;
Collect(key, Find(key,root,0), V);
return V;
}
int main()
{
Trie Mytrie;
Mytrie.Insert("dog");
Mytrie.Insert("cat");
Mytrie.Insert("father");
Mytrie.Insert("ddt");
Mytrie.Insert("fafad");
Mytrie.Insert("cai");
vector<string>S = Mytrie.KeysWithPrefix("fa");
for (int i = 0; i < S.size(); ++i) {
cout << S[i] << " ";
}
cout << endl;
Mytrie.Delete("dog");
vector<string>V = Mytrie.KeysWithPrefix("d");
for (int i = 0; i < V.size(); i++) {
cout << V[i] << " ";
}
cout << endl;
}