Trie树的结构如下:
就根据这个图来建立就好了。
就是删除要考虑几种情况:
1.删除中间的红点
2.删除末红点找到前面的支点(如上图,要删除bcd,就要找到b指的节点,再向下删除,像abd,就要从ab指的节点删掉abd)
代码如下:
// trie树.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "string"
#include "iostream"
#define NUMBERMAX 26
using namespace std;
typedef struct node
{
int number;
struct node *p[NUMBERMAX];
node() {
number = 0;
for (int i = 0; i < NUMBERMAX; i++)
{
p[i] = NULL;
}
}
}node;
class Trie
{
public:
Trie();
~Trie();
bool add(string & s);
bool isExist(string & s);
bool deletes(string & s);
bool printAll();
int numberOfString(string & s);
void clear();
private:
void clear(node * p[NUMBERMAX]);
bool pIsOne(node * p[NUMBERMAX]);
void printCharacter(string s, node * p[NUMBERMAX]);
node * root;
};
bool Trie::printAll()
{
int numberOfPoint = 0;
for (int i = 0; i < NUMBERMAX; i++)
{
if (root->p[i] != NULL)
{
numberOfPoint++;
}
}
if (numberOfPoint == 0)
{
return false;
}
string s;
printCharacter(s, root->p);
cout << endl;
return true;
}
int Trie::numberOfString(string & s)
{
node * p = root;
int index = 0;
for (int i = 0; i < s.length(); i++)
{
index = s.at(i) - 'a';
if (p->p[index] == NULL)
{
return false;
}
p = p->p[index];
}
return p->p[index]->number;
}
void Trie::clear()
{
clear(root->p);
for (int i = 0; i < NUMBERMAX; i++)
{
root->p[i] = NULL;
}
}
bool Trie::deletes(string & s)
{
node * detach = NULL;
node * detachPerant = NULL;
int detachPoint = -1;
node * p = root;
int index = 0;
for (int i = 0; i < s.length(); i++)
{
index = s.at(i) - 'a';
if (p->p[index] == NULL)
{
return false;
}
if (!pIsOne(p->p))
{
detachPerant = p;
detach = p->p[index];
detachPoint = i;
}
if (detachPoint != -1)
{
if (p->number != 0)
{
detachPerant = p;
detach = p->p[index];
detachPoint = i;
}
}
p = p->p[index];
}
if (detachPoint == s.length() - 1)
{
if (p->number != 0)
{
for (int i = 0; i < NUMBERMAX; i++)
{
if (p->p[i] != NULL)
{
p->number = 0;
return true;
}
}
}
}
node * temp = detach;
detachPerant->p[s.at(detachPoint) - 'a'] = NULL;
for (int i = detachPoint + 1; i < s.length(); i++)
{
index = s.at(i) - 'a';
temp = detach->p[index];
delete detach;
detach = temp;
}
delete detach;
return true;
}
void Trie::clear(node * p[NUMBERMAX])
{
for (int i = 0; i < NUMBERMAX; i++)
{
if (p[i] != NULL)
{
clear(p[i]->p);
delete p[i];
}
}
}
bool Trie::pIsOne(node * p[NUMBERMAX])
{
int numberOfPoint = 0;
for (int i = 0; i < NUMBERMAX; i++)
{
if (p[i] != NULL)
{
numberOfPoint++;
}
}
return numberOfPoint == 1 ? true : false;
}
void Trie::printCharacter(string s, node * p[NUMBERMAX])
{
for (int i = 0; i < NUMBERMAX; i++)
{
if (p[i] != NULL)
{
s.push_back(char(i + 'a'));
for (int j = 0; j < p[i]->number; j++)
{
cout << s << " ";
}
printCharacter(s, p[i]->p);
s.pop_back();
}
}
}
bool Trie::isExist(string & s)
{
node * p = root;
int index = 0;
for (int i = 0; i < s.length(); i++)
{
index = s.at(i) - 'a';
if (p->p[index] == NULL)
{
return false;
}
p = p->p[index];
}
return true;
}
bool Trie::add(string& s)
{
node * p = root;
int index = 0;
for (int i = 0; i < s.length(); i++)
{
index = s.at(i) - 'a';
if (p->p[index] == NULL)
{
p->p[index] = new node();
}
p = p->p[index];
}
p->number++;
return true;
}
Trie::Trie()
{
root = new node();
}
Trie::~Trie()
{
clear();
}
int main()
{
string test;
Trie t;
for (int i = 0; i < 10; i++)
{
cout << "输入字符串:";
cin >> test;
t.add(test);
}
if (t.isExist(test))
{
cout << "Yes, " << test << " exist!" << endl;
}
else
{
cout << "No,something wrong!" << endl;
}
t.printAll();
t.deletes(test);
if (!t.isExist(test))
{
cout << "The last one is " << test << ". Yes,it has been deleted!" << endl;
}
else
{
cout << "No,something wrong!" << endl;
}
t.printAll();
system("pause");
return 0;
}