Trie树及其应用

一 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: [email protected]
*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;
	}
}


 

三 测试:

Trie树及其应用_第1张图片

你可能感兴趣的:(Trie树及其应用)