}
用户类.h
#ifndefUSER
#defineUSER
#include"Stack.h"
#include
#include
usingnamespacestd;
classUser//用户类;
{
public:
User();//默认构造函数;
~User();//析构函数;
boolempty();//判空函数;
voidEdit();//密码修改函数;
voidremove();//用户删除函数;
voidsearch(stringname,stringpaw,bool&found,bool&found1);//查找函数,登录操作的辅助函数;
voidinsert(stringname,stringpaw);//插入函数,注册操作的辅助函数;
boolsearch3(stringname);//查找函数,注册操作的辅助函数;
voidgraph(ostream&out)const;//图形输出函数;用于测试AVL的结构;
voidSave_User();//保存函数,将用户信息保存到文件里;
private:
classUserNode//用户节点类;
{
public:
stringusername;//用户名;
stringpassword;//密码;
intbalanceFactor;//AVL结构中的平衡因子;
UserNode*left;//指向左节点的指针;
UserNode*right;//指向右节点的指针;
UserNode()//默认构造函数;
{
balanceFactor=0;//平衡因子的值为0;
left=0;//左指针为0;
right=0;//右指针为0;
}
UserNode(stringname,stringpaw)//显示构造函数,定义参数name和paw;
{
password=paw;//密码的值为paw;
username=name;//用户名为name;
balanceFactor=0;//平衡因子的值为0;
left=0;//左指针为0;
right=0;//右指针为0;
}
};
typedefUserNode*UserNodePointer;
Stackpath;//定义一个Stack类型的变量,用于存储插入路径上的节点;
Stackp;//定义一个Stack类型的变量,保存文件需要;
UserNodePointermyRoot;
voidsearch2(stringname,bool&found,UserNodePointer&locptr,UserNodePointer&parent);//删除操作的辅助函数;
voidgraphAux(ostream&out,intindent,UserNodePointersubtreeRoot)const;//图形输出函数的辅助函数;
voidrelease(UserNodePointersubtreeRoot);//析构函数的辅助函数;
voidSave(UserNodePointersubtreeRoot);//保存函数的辅助函数;
voidRotation(intnewBF,UserNodePointerroot);//旋转函数,用于调整二叉树的结构;
/*=============================右旋函数以及其定义========================================================*/
UserNodePointerR_rotation(UserNodePointerroot)
{
UserNodePointernewRoot=root->left;//将newRoot(新的旋转根)设为原旋转根的左孩子;
root->left=newRoot->right;//原旋转根的左指针指向新旋转根的右节点(可以为0);
newRoot->right=root;//新的旋转根的右指针指向原旋转根;
if(newRoot->balanceFactor==1)//如果原旋转根的左孩子的平衡因子为1;
{
root->balanceFactor=0;//旋转后原旋转根的平衡因子为0;
newRoot->balanceFactor=0;//新的旋转根(即原旋转根的左孩子)的平衡因子也为0;
}
else//其他情况,即原旋转根的左孩子的平衡因子为0;
{//此种情况只有在删除时才会出现;
root->balanceFactor=1;//旋转后原旋转根的平衡因子为1;
newRoot->balanceFactor=-1;//新的旋转根的平衡因子为-1;
}
returnnewRoot;//返回新的旋转根;
}
/*=============================左旋函数以及其定义========================================================*/
UserNodePointerL_rotation(UserNodePointerroot)
{
//左旋函数的操作刚好和右旋操作相反;
UserNodePointernewRoot=root->right;//将newRoot(新的旋转根)设为原旋转根的右孩子;
root->right=newRoot->left;//原旋转根的右指针指向新旋转根的左节点(可以为0);
newRoot->left=root;//新的旋转根的左指针指向原旋转根;
if(newRoot->balanceFactor==-1)//如果原旋转根的右孩子的平衡因子为-1
{
root->balanceFactor=0;//旋转后原旋转根的平衡因子为0;
newRoot->balanceFactor=0;//新的旋转根(即原旋转根的右孩子)的平衡因子也为0;
}
else//其他情况,即原旋转根的右孩子的平衡因子为0;
{
root->balanceFactor=-1;//旋转后原旋转根的平衡因子为-1;
newRoot->balanceFactor=1;//新的旋转根的平衡因子为1;
}
returnnewRoot;//返回新的旋转根;
}
/*=============================右左旋函数以及其定义=====================================================*/
UserNodePointerRL_rotation(UserNodePointerroot)
{
UserNodePointerptr=root->right;//定义辅助指针,指向原旋转根的右孩子;
UserNodePointernewRoot=ptr->left;//将新的旋转根设为旋转根的右孩子的左孩子;
root->right=newRoot->left;//原旋转根的右指针指向新旋转根的左孩子;
ptr->left=newRoot->right;//原旋转根的右孩子的的左指针指向新旋转根的右孩子;
newRoot->right=ptr;//新的旋转根的右指针指向原旋转根的右孩子;
newRoot->left=root;//新的旋转根的左指针指向原旋转根;
switch(newRoot->balanceFactor)//右左旋操作有三种情况;
{
case0:
//情况1:
新节点插入之前,原旋转根的右孩子没有左孩子,新插入的节点成为其左孩子;
root->balanceFactor=0;//旋转后原旋转根的平衡因子为0;
ptr->balanceFactor=0;//原旋转根的右孩子的平衡因子为0;
break;
case1:
//情况2:
新节点插入之前,原旋转根的右孩子有左孩子C,新节点被插入到C的右子树中;
root->balanceFactor=0;//旋转后原旋转根的平衡因子为0;
ptr->balanceFactor=-1;//原旋转根的右孩子的平衡因子为-1;
case-1:
//情况3:
新节点插入之前,原旋转根的右孩子有左孩子C,新节点被插入到C的左子树中;
root->balanceFactor=1;//旋转后原旋转根的平衡因子为1;
ptr->balanceFactor=0;//原旋转根的右孩子的平衡因子为0;
break;
}
newRoot->balanceFactor=0;//新旋转根的平衡因子为0;
returnnewRoot;//返回新的旋转根;
}
/*=============================左右旋函数以及其定义=====================================================*/
UserNodePointerLR_rotation(UserNodePointerroot)//左右旋操作与右左旋操作刚好相反;
{
UserNodePointerptr=root->left;//定义辅助指针,指向原旋转根的左孩子;
UserNodePointernewRoot=ptr->right;//将新的旋转根设为旋转根的左孩子的右孩子;
root->left=newRoot->right;//原旋转根的左指针指向新旋转根的右孩子;
ptr->right=newRoot->left;//原旋转根的左孩子的的右指针指向新旋转根的左孩子;
newRoot->left=ptr;//新的旋转根的左指针指向原旋转根的左孩子;
newRoot->right=root;//新的旋转根的右指针指向原旋转根;
switch(newRoot->balanceFactor)//左右旋操作有三种情况;
{
case0:
//情况1:
新节点插入之前,原旋转根的左孩子没有右孩子,新插入的节点成为其右孩子;
root->balanceFactor=0;//旋转后原旋转根的平衡因子为0;
ptr->balanceFactor=0;//原旋转根的左孩子的平衡因子为0;
break;
case1:
//情况2:
新节点插入之前,原旋转根的左孩子有右孩子C,新节点被插入到C的左子树中;
root->balanceFactor=-1;//旋转后原旋转根的平衡因子为-1;
ptr->balanceFactor=0;//原旋转根的右孩子的平衡因子为0;
case-1:
//情况3:
新节点插入之前,原旋转根的左孩子有右孩子C,新节点被插入到C的右子树中;
root->balanceFactor=0;//旋转后原旋转根的平衡因子为0;
ptr->balanceFactor=1;//原旋转根的左孩子的平衡因子为1;
break;
}
newRoot->balanceFactor=0;//新旋转根的平衡因子为0;
returnnewRoot;//返回新的旋转根;
}
};
#endif
//用户类cpp
#include"User.h"
#include"Stack.h"
#include
#include
#include
#include
usingnamespacestd;
/*=======================================构造函数的定义============================================================================*/
User:
:
User()
{
myRoot=0;
}
/*======================================析构函数的定义=============================================================================*/
User:
:
~User()
{
release(myRoot);//调用析构的辅助函数release;
}
/*=====================================判空函数的定义==============================================================================*/
boolUser:
:
empty()
{
returnmyRoot==0;//返回myRoot等于0;
}
/*=====================================析构函数的辅助函数的定义====================================================================*/
voidUser:
:
release(UserNodePointersubtreeRoot)
{
if(subtreeRoot!
=0)
{
release(subtreeRoot->left);//采用后序遍历实现析构;
release(subtreeRoot->right);
deletesubtreeRoot;
}
}
/*=====================================查找函数(注册操作的辅助函数)的定义========================================================*/
boolUser:
:
search3(stringname)
{
UserNodePointerlocptr=myRoot;//定义辅助指针指向根节点;
boolfound=true;//定义bool类型的变量found为true;
while(found==true&&locptr!
=0)//当found为true且辅助指针不等于0时;
{
if(nameusername)//如果name小于当前节点的用户名;
locptr=locptr->left;//下降到左子树;
elseif(name>locptr->username)//如果name大于当前节点的用户名;
locptr=locptr->right;//下降到右子树;
else
found=false;//若相等,则found为false,循环结束;
}
returnfound;//返回found;
}
/*=====================================BST图形输出函数的定义=======================================================================*/
voidUser:
:
graph(ostream&out)const
{
graphAux(out,0,myRoot);
}
/*=====================================保存操作的辅助函数的定义===================================================================*/
voidUser:
:
Save(UserNodePointersubtreeRoot)
{
if(subtreeRoot!
=0)//用递归的方法;
{
p.push(subtreeRoot);//将二叉树中的所有元素压入栈中;
Save(subtreeRoot->left);
Save(subtreeRoot->right);
}
}
/*=====================================保存函数的定义============================================================================*/
voidUser:
:
Save_User()
{
ofstreamoutfile("user.txt",ios:
:
out);
if(!
outfile)
{
cerr<<"openerror!
"<exit
(1);
}
Save(myRoot);
while(!
p.empty())
{
UserNodePointerlocptr=p.top();//一边出栈,一边将出来的元素读到文件中;
outfile<username<<""<password<p.pop();
}
outfile.close();
}
/*=====================================graph的辅助函数的定义=======================================================================*/
voidUser:
:
graphAux(ostream&out,intindent,UserNodePointersubtreeRoot)const
{
if(subtreeRoot!
=0)
{
graphAux(out,indent