课设(大二下学期)avl

来源:互联网 发布:淘宝上的psp3000 编辑:程序博客网 时间:2024/04/29 16:07
主函数
/*******************************//*project: Dictionary*//*marker: GuoQianru*//*date: 2012/3/2*//******************************/#include <iostream>#include "avl.h"using namespace std;int main(){char opt[100];AVL avl;avl.AVLCreate();avl.AVLExplain();system("PAUSE");system("cls");while(1){avl.ShowMenu();cin >> opt;avl.DealMenu(opt);if(atoi(opt)==4){break;}}return 0;}

头文件
#include <iostream>#include <stack> // 栈容器#include <fstream>#include <string.h>#include <stdlib.h>#define max(a,b) (a>b?a:b)using namespace std;//定义AVLNode结构体struct AVLNode{char word[50];         //单词char promean[200];      //单词词性意思int factor;            //平衡因子,左子树高度减去右子树高度AVLNode *lchild;       //左孩子AVLNode *rchild;       //右孩子};//声明类AVLclass AVL{public:AVL();    //构造函数void AVLExplain();  //软件说明函数void ShowMenu(); //显示主菜单void DealMenu(char *opt);  //处理主菜单选项void AVLCreate();  //创建平衡查找树,从文件中读取数据void DealString(char *buffer, AVLNode *node); //处理整行数据void TxtInsert(AVLNode *node);  //从文件中插入int SureInsert(AVLNode *node);void Search();   //查找函数void ShowSearch();  //显示查找结果void Insert();  //从键盘插入函数void Judgment(AVLNode* node); //判断插入单词是否存在void SortTree();  //调整树的平衡void Delete();  //删除函数int SureDelete();void AidDelete(char *tword);void FindLeft(AVLNode *bt);void FindRight(AVLNode *bt);int Height(AVLNode *bt);  //节点高度void FactValue(AVLNode *bt);   //用后序法计算各factor的数值 void TypeChoose(int n); void FindPivot();  //需找不平衡点的指针int FindType();  //判断旋转类型void LLType();  //LL型void RRType();  //RR型void LRType();  //LR型void RLType();  //RL型void Exit(); //退出函数,并保存文件 void Release(AVLNode *bt);  //释放节点~AVL();   //析构函数private:AVLNode *root;  //根节点int nodenum;    //节点个数AVLNode *pivot;  //当前节点AVLNode *parent;  //pivot的父亲节点};
avl.cpp


#include "avl.h"AVL::AVL(){   //构造函数root = NULL;nodenum = 0;}void AVL::AVLCreate(){  //创建平衡查找树,从文件中读取数据char buffer[300];char docu[6] = " ";docu[1] = '.';docu[2] = 't';docu[3] = 'x';docu[4] = 't';docu[5] = '\0';AVLNode *node;ifstream infile("en.txt", ios::in);if(!infile){for(char ch ='a'; ch<='z'; ch++){docu[0] = ch;ifstream infile1(docu,ios::in);if(!infile1){continue;}while(infile1.getline(buffer, 300, '\n')){node = new AVLNode;DealString(buffer, node);if(stricmp(node->word, "")!=0)TxtInsert(node);elsedelete node;}infile1.close();}cout << "a-z" << endl;}else{while(infile.getline(buffer, 300, '\n')){node = new AVLNode;DealString(buffer, node);if(stricmp(node->word, "")!=0)TxtInsert(node);elsedelete node;}infile.close();cout << "en" << endl;}}void AVL::DealString(char *buffer, AVLNode *node){ //字符串处理函数int i = 0;int j = 0;memset(node->word, 0, sizeof(node->word));memset(node->promean, 0, sizeof(node->promean));while(buffer[i]!=' '){node->word[i] = buffer[i];i++;}while(buffer[i]==' '){i++;}while(buffer[i]!='\0'){node->promean[j] = buffer[i];j++;i++;}}void AVL::AVLExplain(){    //欢迎界面cout<<"********************************"<<endl;cout << "     欢迎使用英汉小字典!" << endl;cout<<"********************************"<<endl;}void AVL::Search(){   //以单词拼写为关键字的查找函数char tword[50];pivot = root;if(root==NULL){   //树为空的情况cout << "对不起,字典为空,您无法查找!" << endl;return;}cout << "请输入您要查找的词" << endl;cin >> tword;while((pivot!=NULL)&&(stricmp(tword, pivot->word)!=0)){if(stricmp(tword, pivot->word)<0){   //查找数据小于当前数据,向左移parent = pivot;pivot = pivot->lchild;}else{  //查找数据大于当前数据,向右移parent = pivot;pivot = pivot->rchild;}}}void AVL::ShowSearch(){if(pivot!=NULL){cout << "  恭喜您,查找成功!" << endl;cout << "您查找的单词是  " << pivot->word << endl;cout << "该单词的词性和词义是  " << pivot->promean << endl;}else if(root!=NULL){cout << "对不起,查找失败!" << endl;cout << "您要查找的单词不存在!" << endl;}}void AVL::TxtInsert(AVLNode *node){  //从文件中输入    node->lchild = NULL;node->rchild = NULL;node->factor = 0;nodenum++;    if(root==NULL){root = node;return;}pivot = root;while(pivot!=NULL){if(stricmp(node->word, pivot->word)<0){   //查找数据小于当前数据,向左移parent = pivot;pivot = pivot->lchild;}else{  //查找数据大于当前数据,向右移parent = pivot;pivot = pivot->rchild;}}if(stricmp(node->word, parent->word)>0){parent->rchild = node;}else{parent->lchild = node;}SortTree();  //调整树的平衡}void AVL::Insert(){  //插入函数AVLNode *node;node = new AVLNode;cout << endl << "请您输入您要插入的单词!" << endl;cout << "该单词为 " << endl;cin >> node->word;pivot = root;Judgment(node);if(pivot!=NULL && stricmp(node->word, pivot->word)==0){cout << "您要查找的单词已经存在! " << endl;delete node;return;}cout << "请输入该单词的词性和词义!  "<<endl;cin >> node->promean;system("cls");if(SureInsert(node)==0){cout << "将不进行插入操作!" << endl;delete node;return;}if(root==NULL){root = node;}else if(stricmp(node->word, parent->word)>0){parent->rchild = node;}else{parent->lchild = node;}node->lchild = NULL;node->rchild = NULL;node->factor = 0;nodenum++;SortTree();cout << "恭喜您,该单词已成功插入! " << endl;}int AVL::SureInsert(AVLNode *node){system("cls");cout << "你要插入的单词是 " << node->word<< endl;cout << "单词的词性意思是" << node->promean << endl << endl;cout << "你确定要插入吗? 确定请按“Y”或“y”,否则按任意键!" << endl;char s[100];cin >> s;if(stricmp(s, "y")==0)return 1;return 0;}void AVL::Judgment(AVLNode* node){ //判断插入单词是否存在while((pivot!=NULL)&&(stricmp(node->word, pivot->word)!=0)){if(stricmp(node->word, pivot->word)<0){   //查找数据小于当前数据,向左移parent = pivot;pivot = pivot->lchild;}else{  //查找数据大于当前数据,向右移parent = pivot;pivot = pivot->rchild;}}}void AVL::SortTree(){  //调整树的平衡FactValue(root);FindPivot();if(pivot!=NULL){TypeChoose(FindType());FactValue(root);}}void AVL::Delete(){  //删除函数if(root==NULL){   //树为空cout << "字典为空,您现在不能实现删除功能! " << endl;system("PAUSE");system("cls");}else{char tword[50];system("cls");cout << "请输入您要删除的单词! " << endl;cin >> tword;pivot = root;while(pivot!=NULL && stricmp(tword, pivot->word)!=0){if(stricmp(tword, pivot->word)>0){parent = pivot;pivot = pivot->rchild;}else{parent = pivot;pivot = pivot->lchild;}}system("cls");if(pivot!=NULL&&stricmp(tword, pivot->word)==0){ //找到要删除数据if(SureDelete()==1){AidDelete(tword);nodenum--;SortTree();cout << "恭喜您单词成功删除! " << endl;}else{cout << "该单词将不会被删除!" << endl;}}else{  //删除数据不存在的情况cout << "删除失败,您要删除的单词不存在! " << endl;}}}int AVL::SureDelete(){cout << "你要删除的单词是 " << pivot->word << endl;cout << "删除单词的词性和意思是 " << pivot->promean <<endl << endl;cout << "你确定要删除吗? 确定请按“Y”或“y”,否则按任意键!" << endl;char s[100];cin >> s;if(stricmp(s, "y")==0)return 1;return 0;}void AVL::AidDelete(char *tword){AVLNode *bt;if(pivot->lchild==NULL && pivot->rchild==NULL){ //删除节点为叶子节点的时候bt = pivot;if(stricmp(tword, root->word)==0){  //删除节点为根结点,且根节点没有左右好、孩子root = NULL;}else{  //不为根节点,为普通的叶子节点的时候if(stricmp(tword, parent->word)>0){parent->rchild = NULL;}else{parent->lchild = NULL;}}nodenum--;delete bt; //释放bt点的空间}else{ //删除节点存在左右孩子if(pivot->lchild!=NULL){  //寻找左子树的最大替代点bt = pivot->lchild;FindLeft(bt);}else{  //寻找右子树的最小替代点bt = pivot->rchild;FindRight(bt);}}}void AVL::FindLeft(AVLNode *bt){AVLNode *btparent;while(bt->rchild!=NULL){btparent = bt;bt = bt->rchild;}//用bt代替pivotstrcpy(pivot->word, bt->word);strcpy(pivot->promean, bt->promean);if(pivot->lchild==bt){  //bt是左子树中的最大代替点pivot->lchild = bt->lchild;}else{btparent->rchild = bt->lchild;}delete bt;}void AVL::FindRight(AVLNode *bt){AVLNode *btparent;while(bt->lchild!=NULL){btparent = bt;bt = bt->lchild;}//bt代替pivotstrcpy(pivot->word, bt->word);strcpy(pivot->promean, bt->promean);if(pivot->rchild==bt){pivot->rchild = bt->rchild;}else{btparent->lchild = bt->rchild;}delete bt;}int AVL::Height(AVLNode *bt){ //节点高度if(bt==NULL){return 0;}return max(Height(bt->rchild),Height(bt->rchild))+1;}void AVL::FactValue(AVLNode *bt){   //用后序法计算各factor的数值if(bt!=NULL){FactValue(bt->lchild);FactValue(bt->rchild);bt->factor = Height(bt->lchild) - Height(bt->rchild);}}void AVL::FindPivot(){ //需找不平衡点的指针AVLNode *bt;int i;bt = root;pivot = NULL;parent = root;for(i=1; i<=nodenum; i++){//寻找factor的绝对值大于1的节点if(bt->factor>1 || bt->factor<-1){pivot = bt;break;}if(bt->factor>0){ //左子树高于右子树时parent = bt;bt = bt->lchild;}else if(bt->factor>0){   //右子树高于左子树parent = bt;bt = bt->rchild;}}}int AVL::FindType(){  //判断旋转类型int mark = 0;int n = 2;AVLNode *bt = pivot;while(n--){if(bt->factor>0){  //左子树高bt = bt->lchild;if(mark==0){mark += 10;}else{mark++;}}else if(bt->factor<0){bt = bt->rchild;if(mark==0){mark+=20;}else{mark+=2;}}}//传回值11,12,21,22分别代表LL,LR,RR,RL型return mark;}void AVL::TypeChoose(int n){switch(n){case 11:LLType();break;case 12:LRType();break;case 21:RLType();break;case 22:RRType();break;}}void AVL::LLType(){ //LL型AVLNode *pivot_next, *temp;pivot_next = pivot->lchild;temp = pivot_next->rchild;pivot_next->rchild = pivot;pivot->lchild = temp;if(pivot==root){   //pivot为根节点root = pivot_next;}else{if(stricmp(pivot->word, parent->word)>0){parent->lchild = pivot_next;}else{parent->rchild = pivot_next;}}}void AVL::RRType(){  //RR型AVLNode *pivot_next, *temp;pivot_next = pivot->rchild;temp = pivot_next->lchild;pivot_next->lchild = pivot;pivot->rchild = temp;if(pivot==root){   //pivot为根节点root = pivot_next;}else{if(stricmp(pivot->word, parent->word)>0){parent->lchild = pivot_next;}else{parent->rchild = pivot_next;}}}void AVL::LRType(){  //LR型AVLNode *pivot_next, *temp;pivot_next = pivot->lchild;temp = pivot_next->rchild;pivot->lchild = temp->rchild;pivot_next->rchild = temp->lchild;temp->rchild = pivot;temp->lchild = pivot_next;if(root==pivot){root = temp;}else{if(stricmp(pivot->word, parent->word)>0){parent->lchild = pivot_next;}else{parent->rchild = pivot_next;}}}void AVL::RLType(){  //RL型AVLNode *pivot_next, *temp;pivot_next = pivot->rchild;temp = pivot_next->lchild;pivot->rchild = temp->rchild;pivot_next->lchild = temp->rchild;temp->lchild = pivot;temp->rchild = pivot_next;if(root==pivot){root = temp;}else{if(stricmp(pivot->word, parent->word)>0){parent->lchild = pivot_next;}else{parent->rchild = pivot_next;}}}void AVL::Exit(){   //退出时以中序遍历保存文件fstream outfile;outfile.open("en.txt", ios::out);if (!outfile){cout<<"can't open file!!"<<endl;abort();}stack<AVLNode*> q;AVLNode *bt;bt = root;while(bt!=NULL || !q.empty()){while(bt!=NULL){q.push(bt);bt = bt->lchild;}if(!q.empty()){bt = q.top();q.pop();outfile << bt->word;outfile <<"  ";outfile << bt->promean<<endl;bt = bt->rchild;}}outfile.close();cout << "谢谢您的使用!" << endl;system("PAUSE");}void AVL::ShowMenu(){  //显示主菜单cout << endl;cout <<"    ****************************************************" << endl;cout <<"    *********************主菜单**************************"<<endl;cout <<"    *************1   ----        查找********************"<< endl;cout <<"    *************2   ----        插入********************"<<endl;cout <<"    *************3   ----        删除********************"<<endl;cout <<"    *************4   ----        退出********************"<<endl;cout <<"    *****************************************************" << endl;cout << endl;cout <<"请您选择1到4之间的数:"<<endl;cout << endl;}void AVL::DealMenu(char *opt){ //处理主菜单选项int n = atoi(opt);switch(n){case 1:system("cls");Search();ShowSearch();system("PAUSE");system("cls");break;case 2:system("cls");Insert();system("PAUSE");system("cls");break;case 3:system("cls");Delete();system("PAUSE");system("cls");break;case 4:Exit();system("PAUSE");system("cls");break;default:cout << "您输入的数不是1到4之间的数,请重新输入!" << endl;system("PAUSE");system("cls");}}void AVL::Release(AVLNode *bt){  //释放节点if(bt!=NULL){Release(bt->lchild);Release(bt->rchild);delete bt;}}AVL::~AVL(){ //析构函数Release(root);}

不足:

2.1 再次使用时,数据不从二十六个文件中读取

 该程序初次使用时,从二十六个文件中读取数据;初次使用完毕后,数据保存到en.txt文件中;以后再次使用时,从en.txt中读取数据。

2.2文件读入问题,自己的解决办法不够正规,应尝试正规做法。

2.3没有用到动态显示

  看到用同学用到了单词查询、插入、删除过程中用到了动态显示,觉得很好。后来由于时间原因,没有用上。

2.4 没有用到界面

总感觉,有界面才叫真正的软件。很遗憾,这次没有用到界面。




	
				
		
原创粉丝点击