1、利用AVL高度平衡的二叉树实现登录系统/界面类,.h文件#ifndef MENU#define MENU#includeusing namespace std;class Menupublic: void Menu_Login(); /登录界面(主界面); void Menu_Operator(); /操作界面; void Menu_Quit(); /结束界面;;#endif/界面,.cpp#includeMenu.h#includeusing namespace std;/*=主界面=*/void Menu:Menu_Login() system(cls); /清屏; coutendl; c
2、outendl; coutendl; coutendl; cout*欢迎进入登录系统*endl; cout =endl; cout * 1.用户登录 *endl; cout * 2.用户注册 *endl; cout * 0. 结束 *endl; cout * 请选择: *endl; cout =endl; coutendl;/*=操作界面=*/void Menu:Menu_Operator() system(cls); coutendl; coutendl; coutendl; coutendl; cout =endl; cout * 1.修改密码 *endl; cout * 2.删除用户 *
3、endl; cout * 0.返回上层 *endl; cout * 请选择 *endl; cout =endl;/*=结束界面=*/void Menu:Menu_Quit() system(cls); coutendl; coutendl; coutendl; coutendl; cout =endl; cout *endl; cout *感 使 用*endl; cout *endl; cout =endl;用户类 .h#ifndef USER#define USER#include Stack.h#include #include using namespace std;class User
4、 /用户类;public: User(); /默认构造函数; User(); /析构函数; bool empty(); /判空函数; void Edit(); /密码修改函数; void remove(); /用户删除函数; void search(string name,string paw,bool &found,bool &found1); /查找函数,登录操作的辅助函数; void insert(string name,string paw); /插入函数,注册操作的辅助函数; bool search3(string name); /查找函数,注册操作的辅助函数; void graph
5、(ostream &out) const; /图形输出函数;用于测试AVL的结构; void Save_User(); /保存函数,将用户信息保存到文件里;private: class UserNode /用户节点类; public: string username; /用户名; string password; /密码; int balanceFactor; /AVL结构中的平衡因子; UserNode *left; /指向左节点的指针; UserNode *right; /指向右节点的指针; UserNode() /默认构造函数; balanceFactor=0; /平衡因子的值为0; l
6、eft=0; /左指针为0; right=0; /右指针为0; UserNode(string name,string paw) /显示构造函数,定义参数name和paw; password=paw; /密码的值为paw; username=name; /用户名为name; balanceFactor=0; /平衡因子的值为0; left=0; /左指针为0; right=0; /右指针为0; ; typedef UserNode * UserNodePointer; Stack path; /定义一个Stack类型的变量,用于存储插入路径上的节点; Stack p; /定义一个Stack类型
7、的变量,保存文件需要; UserNodePointer myRoot; void search2(string name,bool &found,UserNodePointer &locptr,UserNodePointer &parent); /删除操作的辅助函数; void graphAux(ostream &out,int indent,UserNodePointer subtreeRoot) const; /图形输出函数的辅助函数; void release(UserNodePointer subtreeRoot); /析构函数的辅助函数; void Save(UserNodePoin
8、ter subtreeRoot); /保存函数的辅助函数; void Rotation(int newBF,UserNodePointer root); /旋转函数,用于调整二叉树的结构;/*=右旋函数以及其定义=*/ UserNodePointer R_rotation(UserNodePointer root) UserNodePointer newRoot=root-left; /将newRoot(新的旋转根)设为原旋转根的左孩子; root-left=newRoot-right; /原旋转根的左指针指向新旋转根的右节点(可以为0); newRoot-right=root; /新的旋转根
9、的右指针指向原旋转根; if(newRoot-balanceFactor=1) /如果原旋转根的左孩子的平衡因子为1; root-balanceFactor=0; /旋转后原旋转根的平衡因子为0; newRoot-balanceFactor=0; /新的旋转根(即原旋转根的左孩子)的平衡因子也为0; else /其他情况,即原旋转根的左孩子的平衡因子为0; /此种情况只有在删除时才会出现; root-balanceFactor=1; /旋转后原旋转根的平衡因子为1; newRoot-balanceFactor=-1; /新的旋转根的平衡因子为-1; return newRoot; /返回新的旋
10、转根; /*=左旋函数以及其定义=*/ UserNodePointer L_rotation(UserNodePointer root) /左旋函数的操作刚好和右旋操作相反; UserNodePointer newRoot=root-right; /将newRoot(新的旋转根)设为原旋转根的右孩子; root-right=newRoot-left; /原旋转根的右指针指向新旋转根的左节点(可以为0); newRoot-left=root; /新的旋转根的左指针指向原旋转根; if(newRoot-balanceFactor=-1) /如果原旋转根的右孩子的平衡因子为-1 root-balan
11、ceFactor=0; /旋转后原旋转根的平衡因子为0; newRoot-balanceFactor=0; /新的旋转根(即原旋转根的右孩子)的平衡因子也为0; else /其他情况,即原旋转根的右孩子的平衡因子为0; root-balanceFactor=-1; /旋转后原旋转根的平衡因子为-1; newRoot-balanceFactor=1; /新的旋转根的平衡因子为1; return newRoot; /返回新的旋转根; /*=右左旋函数以及其定义=*/ UserNodePointer RL_rotation(UserNodePointer root) UserNodePointer
12、ptr=root-right; /定义辅助指针,指向原旋转根的右孩子; UserNodePointer newRoot=ptr-left; /将新的旋转根设为旋转根的右孩子的左孩子; root-right=newRoot-left; /原旋转根的右指针指向新旋转根的左孩子; ptr-left=newRoot-right; /原旋转根的右孩子的的左指针指向新旋转根的右孩子; newRoot-right=ptr; /新的旋转根的右指针指向原旋转根的右孩子; newRoot-left=root; /新的旋转根的左指针指向原旋转根; switch(newRoot-balanceFactor) /右左旋
13、操作有三种情况; case 0: /情况1:新节点插入之前,原旋转根的右孩子没有左孩子,新插入的节点成为其左孩子; root-balanceFactor=0; /旋转后原旋转根的平衡因子为0; ptr-balanceFactor=0; /原旋转根的右孩子的平衡因子为0; break; case 1: /情况2:新节点插入之前,原旋转根的右孩子有左孩子C,新节点被插入到C的右子树中; root-balanceFactor=0; /旋转后原旋转根的平衡因子为0; ptr-balanceFactor=-1; /原旋转根的右孩子的平衡因子为-1; case -1: /情况3:新节点插入之前,原旋转根的
14、右孩子有左孩子C,新节点被插入到C的左子树中; root-balanceFactor=1; /旋转后原旋转根的平衡因子为1; ptr-balanceFactor=0; /原旋转根的右孩子的平衡因子为0; break; newRoot-balanceFactor=0; /新旋转根的平衡因子为0; return newRoot; /返回新的旋转根; /*=左右旋函数以及其定义=*/ UserNodePointer LR_rotation(UserNodePointer root) /左右旋操作与右左旋操作刚好相反; UserNodePointer ptr=root-left; /定义辅助指针,指向
15、原旋转根的左孩子; UserNodePointer newRoot=ptr-right; /将新的旋转根设为旋转根的左孩子的右孩子; root-left=newRoot-right; /原旋转根的左指针指向新旋转根的右孩子; ptr-right=newRoot-left; /原旋转根的左孩子的的右指针指向新旋转根的左孩子; newRoot-left=ptr; /新的旋转根的左指针指向原旋转根的左孩子; newRoot-right=root; /新的旋转根的右指针指向原旋转根; switch(newRoot-balanceFactor) /左右旋操作有三种情况; case 0: /情况1:新节点
16、插入之前,原旋转根的左孩子没有右孩子,新插入的节点成为其右孩子; root-balanceFactor=0; /旋转后原旋转根的平衡因子为0; ptr-balanceFactor=0; /原旋转根的左孩子的平衡因子为0; break; case 1: /情况2:新节点插入之前,原旋转根的左孩子有右孩子C,新节点被插入到C的左子树中; root-balanceFactor=-1; /旋转后原旋转根的平衡因子为-1; ptr-balanceFactor=0; /原旋转根的右孩子的平衡因子为0; case -1: /情况3:新节点插入之前,原旋转根的左孩子有右孩子C,新节点被插入到C的右子树中; r
17、oot-balanceFactor=0; /旋转后原旋转根的平衡因子为0; ptr-balanceFactor=1; /原旋转根的左孩子的平衡因子为1; break; newRoot-balanceFactor=0; /新旋转根的平衡因子为0; return newRoot; /返回新的旋转根; ;#endif/用户类cpp#include User.h#include Stack.h#include#include#include#includeusing namespace std;/*=构造函数的定义=*/User:User() myRoot=0;/*=析构函数的定义=*/User:Us
18、er() release(myRoot); /调用析构的辅助函数release;/*=判空函数的定义=*/bool User:empty() return myRoot=0; /返回myRoot等于0;/*=析构函数的辅助函数的定义=*/void User:release(UserNodePointer subtreeRoot) if(subtreeRoot!=0) release(subtreeRoot-left); /采用后序遍历实现析构; release(subtreeRoot-right); delete subtreeRoot; /*=查找函数(注册操作的辅助函数)的定义=*/boo
19、l User:search3(string name) UserNodePointer locptr=myRoot; /定义辅助指针指向根节点; bool found=true; /定义bool类型的变量found为true; while(found=true&locptr!=0) /当found为true且辅助指针不等于0时; if(nameusername) /如果name小于当前节点的用户名; locptr=locptr-left; /下降到左子树; else if(namelocptr-username) /如果name大于当前节点的用户名; locptr=locptr-right;
20、/下降到右子树; else found=false; /若相等,则found为false,循环结束; return found; /返回found;/*=BST图形输出函数的定义=*/void User:graph(ostream &out) const graphAux(out,0,myRoot);/*=保存操作的辅助函数的定义=*/void User:Save(UserNodePointer subtreeRoot) if(subtreeRoot!=0) /用递归的方法; p.push(subtreeRoot); /将二叉树中的所有元素压入栈中; Save(subtreeRoot-left
21、); Save(subtreeRoot-right); /*=保存函数的定义=*/void User:Save_User() ofstream outfile(user.txt,ios:out); if(!outfile) cerropen error!endl; exit(1); Save(myRoot); while(!p.empty() UserNodePointer locptr=p.top(); /一边出栈,一边将出来的元素读到文件中; outfileusername passwordendl; p.pop(); outfile.close();/*=graph的辅助函数的定义=*/void User:graphAux(ostream &out,int indent,UserNodePointer subtreeRoot) const if(subtreeRoot!=0) graphAux(out,indent