一 Trie树
可参照百度百科: http://baike.baidu.com/view/1436495.htm
二 Trie树的构造及应用
/*
This is a free Program, You can modify or redistribute it under the terms of GNU
*Description:Trie树及其应用
*Language: C++
*Development Environment: VC6.0
*Author: Wangzhicheng
*E-mail: 2363702560@qq.com
*Date: 2013/1/6
*/
#include <iostream>
#include <cstdlib>
#include <vector>
#include <string>
#include <cctype>
#include <ctime>
#include <algorithm>
using namespace std;
const int Num = 26; //定义26个字母
/*
* 定义结点类型
* UNCOMPLETED表示该结点对应的字符串还未创建完毕
* COMPLETED表示该结点对应的字符串已经创建完毕
*/
enum NodeType { UNCOMPLETED, COMPLETED };
class Trie; //向前引用
/*
* 定义结点类
* @type: 结点类型
* @ch: 结点所含的字符
* @child: 结点孩子指针向量
*/
class Node {
private:
friend class Trie;
NodeType type;
char ch;
vector<Node *>child;
};
/*
* 定义Trie树
*/
class Trie {
private:
Node *root; //根结点
/*
* 创建新结点
* @ch: 结点含有的字符
*/
Node *newNode(char ch) {
Node *p=new Node;
if(!p) {
cerr<<"内存不足!"<<endl;
exit(1);
}
p->type = UNCOMPLETED;
p->ch = ch;
p->child.assign(Num, NULL);
return p;
}
/*
* 返回字符在孩子指针向量中的位置
*/
int index(char ch) {
if(isupper(ch)) ch = tolower(ch);
return ch - 'a';
}
/*
* 删除指针ptr所指向的trie子树, 采用递归遍历子树
*/
void delTrie(Node *&ptr) {
vector<Node *>::iterator it;
if(ptr == NULL) return;
for(it = ptr->child.begin(); it != ptr->child.end(); it++) {
if(*it && (*it)->type != COMPLETED) delTrie(*it);
delete *it;
*it = NULL;
}
delete ptr;
ptr = NULL;
}
/*
* 遍历Trie树
*/
void tranverse(Node *ptr) {
vector<Node *>::iterator it;
if(ptr == NULL) return;
for(it = ptr->child.begin(); it != ptr->child.end(); it++) {
if(*it) cout<<(*it)->ch;
if(*it && (*it)->type != COMPLETED) {
tranverse(*it);
}
}
cout<<endl;
}
public:
/*
* 向trie树中插入单词word
*/
void insertNode(string word) {
Node *ptr = root;
string::iterator it;
int pos;
for(it= word.begin(); it != word.end(); it++) {
pos = index(*it);
if(ptr->child[pos] == NULL) {
ptr->child[pos] = newNode(*it);
}
ptr = ptr->child[pos];
}
ptr->type = COMPLETED;
}
/*
* 在Trie树中删除单词word
*/
void removeNode(string word) {
Node *ptr = root;
Node *del;
int pos;
pos = index(word[0]);
ptr = ptr->child[pos];
while(ptr) {
del = ptr;
ptr = ptr->child[pos];
delete del;
}
root->child[pos] = ptr;
}
Trie() {
root = newNode('@'); //创建根结点
}
~Trie() {
delTrie(root);
}
/*
* 在Trie树中查找单词word,找到返回true,否则返回false
*/
bool find(const string &word) {
Node *ptr = root;
string::const_iterator it;
int pos;
for(it = word.begin(); it != word.end(); it++) {
pos = index(*it);
if(ptr->child[pos] == NULL) break;
ptr = ptr->child[pos];
}
return it == word.end() && ptr->type == COMPLETED;
}
void tranverse() {
tranverse(root);
}
};
void main() {
cout<<"Trie树查询系统V1.0"<<endl;
Trie t;
string word;
string::const_iterator it;
clock_t start, finish;
double duration;
while(true) {
cout<<"请输入要查询的英语单词(输入exit退出):";
cin>>word;
for(it = word.begin(); it != word.end(); it++) {
if(isupper(*it) || islower(*it)) continue;
else {
cerr<<"输入单词非法!"<<endl;
exit(1);
}
}
if(word == "exit" ) break;
start = clock();
if(t.find(word) == false) {
cerr<<"您输入的单词未查找,现在向trie树插入该单词."<<endl;
t.insertNode(word);
continue;
}
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
cout<<word<<"已经查到, 查找时间是: "<<duration<<"秒"<<endl;
}
}
三 测试: