用户登录系统.docx
- 文档编号:10030488
- 上传时间:2023-02-08
- 格式:DOCX
- 页数:31
- 大小:237.05KB
用户登录系统.docx
《用户登录系统.docx》由会员分享,可在线阅读,更多相关《用户登录系统.docx(31页珍藏版)》请在冰豆网上搜索。
用户登录系统
数据结构大型实验
2015/2016
(1)
实验题目用户登录系统
学生姓名
学生学号—
主要工作树的结构、框架编写
负责人
学生班级
任课教师
提交日期
2016.1.2
计算机科学与技术学院
用户登录系统
一.实验题目和要求:
【问题描述】
在登录服务器系统时,都需要验证用户名和密码,如telnet远程登录服务
器。
用户输入用户名和密码后,服务器程序会首先验证用户信息的合法性。
由于
用户信息的验证频率很高,系统有必要有效地组织这些用户信息,从而快速查找
和验证用户。
另外,系统也会经常会添加新用户、删除老用户和更新用户密码等操作,因此,系统必须采用动态结构,在添加、删除或更新后,依然能保证验证过程的快速。
请采用相应的数据结构模拟用户登录系统,其功能要求包括用户登录、用户密码更新、用户添加和用户删除等。
【基本要求】
1.要求自己编程实现二叉树结构及其相关功能,以存储用户信息,不允许使用标准模板类的二叉树结构和函数。
同时要求根据二叉树的变化情况,进行相应的平衡操作,即AVL平衡树操作,四种平衡操作都必须考虑。
测试时,各种情况都需要测试,并附上测试截图;
2.要求采用类的设计思路,不允许出现类以外的函数定义,但允许友元函数。
主函数中只能出现类的成员函数的调用,不允许出现对其它函数的调用。
3.要求采用多文件方式:
.h文件存储类的声明,.cpp文件存储类的实现,主函数main存储在另外一个单独的cpp文件中。
如果采用类模板,则类的声明和实现都放在.h文件中。
4.要求源程序中有相应注释;
5.不强制要求米用类模板,也不要求米用可视化窗口;
6.要求测试例子要比较详尽,各种极限情况也要考虑到,测试的输出信息要详
细易懂,表明各个功能的执行正确;
7.要求采用VisualC++6.0及以上版本进行调试;
设计思路:
1.系统总体设计:
采用平衡二叉查找树(AVL,以用户名(IP)作为比较的关键词进行插入。
平衡二叉查找树是在二叉搜索树(BST的基础上进行了优化,使得树基本达到平衡。
定义内部类userNode来存储AVL树的节点信息。
2.系统功能设计:
要创建一颗包含用户名和用户密码的二叉树,要能适应频繁的查找,因为每
个用户名是唯一的,将用户名(string类型)作为AVL树的比较参数,这样就可以实现快速的插入、删除和查找,重定义userNode类的比较函数。
AVL树是用模板类实现的,这样就可以直接比较两个用户类,方便了很多。
图1系统功能结构图
3.类的设计:
//节点的类
classuserNode
{
private:
stringname;
stringpassword;
shortintheight;
public:
userNode*left;
userNode*right;
userNode(conststring&name,conststring&password);
userNode(constuserNode&temp);
voidsetName(conststring&name);
voidsetPassword(conststring&password);
stringgetName();
stringgetPassword();
intgetHeight();
voidchangeHeight(constintheight);//改变树的高度boolcheckName(conststring&name);
};
//树的类
classtree
{
private:
userNode*root;
public:
tree();
~tree();
voidinsert_node(userNode*&t,userNode&temp);
voidinsert_node(userNode&temp);//新建一个节点
voidremove(userNode*&r,userNode*&temp);
voidremove(userNode*&temp);//删除一个节点
voidclear(userNode*t);
voidclear();
voidprint();
voidprint(intindex,userNode*r);//输岀一棵树
voidPrint();
voidPrint(ofstream&ofile,userNode*&r);//写入文件
voidrotateL(userNode*&r);//左旋
voidrotateR(userNode*&r);//右旋
voidrotateDoubleLR(userNode*&r);//左右旋
voidrotateDoubleRL(userNode*&r);//右左旋
voidrightBalance(userNode*&r);
voidleftBalance(userNode*&r);
userNode*findNode(strings);//搜索一个节点
userNode*searchLeftMaxNode(userNode*&r,userNode*&R);
};
//框架类
classframe
{
treemyTree;
public:
frame();
voidview();//显示主界面
voidLogin();//登录界面
voidtestInsert();//插入一个节点
voidprintTree();//画岀一棵树
};
4.主程序的设计:
图2类的调用
三•调试分析:
1.技术难点分析:
(1)查询操作时,怎么能找到相应用户的节点?
考虑到用户名的唯一性,所以将用户名作为AVL树的关键词,以字符串来比较大小,进行排序,重定义userNode类的比较操作符,只比较IP,因此,在查询的时候,新建一个userNode的对象,其IP赋值为所要查询的IP,然后调用查找函数,可找到对应的点
(2)AVL树的实现
看书,上网查询。
先了解二叉查找树(BST的实现,二叉查找树(BST是一种很好的数据结构,它的特点是,对其任一节点,都满足该节点的左子树的所有点的值都小于该节点,而右子树则是大于。
我采用链表来实现它,创建关于节点的
一个类Node,内含描述该节点的值,及左右指针。
我定义insert_node()函
数来实现新节点的插入。
AVL树相对于BST树,多了平衡两字,树都有高度,而AVL树就是要求每一个节点的左子树和右子树的高度差不超过1,这样就能使其
尽可能的减小整棵树的高度,使时间复杂度能稳定在O(logN),但我们不可能去约束用户的输入,因此,引入了四种旋转:
I是新插入的节点
图4左旋
图5先右旋再左旋
图6先左旋再右旋
(3)修改密码或删除用户后如何返回上一界面?
经反复修改,未果,遂放弃。
2.调试错误分析:
(1)登陆时密码要正确
rD:
\C++\^^iS®2015\DateStructureexpwriment\Debug\Date1欢迎进人用户登录界面!
(输人00逅回上—界面〉
请输入账号;
159
请输入密码;
图7用户登录界面
(2)登陆时用户要存在
■D:
\C++型试验2015\DateStructureexpwriment\Debug\DateStructur.^欢迎进入用户登录界面「(输入盹返回上一界面〉
请输入账号|
12
图8用户不存在界面
(3)新建用户名不能已存在
■D:
\C+型试验2015\DateStructureexpwnment\Debug\DateSx
欢迎进入用户注册界面!
t输入胴追回上一界面〉
请输入用户名:
159
该用户已存在!
请按任意键继绫…
图9用户名已存在界面
四、测试结果分析:
1)
主界面
■D:
\C++U<型试验2015\DateStructureexpwriment\Debug\DateStructur...
一用图一入形一进录鵜岀一迎登注一黒-「..:
」2.3,4.
攫狗拼音输入法全:
图10主界面
2)登录界面
■。
:
\匚++伏型试验2015\DateStructureexpwriment\Debug\DateStructur.,.欢迎进入用户聲录界面!
t输入歸返回上一鼎面亍
请输入账号:
159
请输入密码:
密码输入正确,成功登陆
捜狗拼音输入进也
图ii登录界面
3)注册界面
■D:
\C++\±^tj^^2015\DateStructureexpwriment\Debug\DateStructur...-眉迎进入用户注册界面!
<输入唾回上一界面〉
请输入用户名:
23
请输入密码:
23
注册成功!
请按任意键继续•-•■
扌叟狗捋音输人法全:
图12注册界面
4)树图
5)修改密码
I"1D:
\C++V^T3C^2015\DateStructureeKpwriirient\Debug\DateStructur...-n!
输入新密码;六
请按農键继续•….
扌叟狗拼音输入进全:
图14修改密码
6)删除用户
•D:
\C+15\DateStructureexpwriment\Debug\DateStructur..."隸迎进入用户登录界面It输入ee返回上_
请输入账号:
159
请输入密码:
23
密码输入正礁,成功登陆
h®键继续…-
搜狗拼音输入进全:
图15删除用户界面
五、附录:
Node.h
#ineludevstring>
#inelude
#inelude
#include
#inelude
elassuserNode
{
private:
stringname;
stringpassword;
shortintheight;
public:
userNode*left;
userNode*right;
userNode(eonststring&name,conststring&password);
userNode(eonstuserNode&temp);
voidsetName(eonststring&name);
voidsetPassword(conststring&password);
stringgetName();
stringgetPassword();
intgetHeight();
voidchangeHeight(constintheight);//改变树的高度boolcheckName(conststring&name);
};
Tree.h
#include"node.h"
#include
classtree
{
private:
userNode*root;
public:
tree();
~tree();
voidinsert_node(userNode*&t,userNode&temp);
voidinsert_node(userNode&temp);//新建一个节点
voidremove(userNode*&r,userNode*&temp);
voidremove(userNode*&temp);//删除一个节点
voidclear(userNode*t);
voidclear();
voidprint();
voidprint(intindex,userNode*r);//输岀一棵树
voidPrint();
voidPrint(ofstream&ofile,userNode*&r);//写入文件
voidrotateL(userNode*&r);//左旋
voidrotateR(userNode*&r);//右旋
voidrotateDoubleLR(userNode*&r);//左右旋
voidrotateDoubleRL(userNode*&r);//右左旋
voidrightBalance(userNode*&r);
voidleftBalance(userNode*&r);
userNode*findNode(strings);//搜索一个节点
userNode*searchLeftMaxNode(userNode*&r,userNode*&R);
};
Frame.h
#include"tree.h"
classframe
{
treemyTree;
public:
frame();
voidview();//显示主界面
voidLogin();//登录界面
voidtestInsert();//插入一个节点
voidprintTree();//画岀一棵树
};
Node.cpp
#include"node.h"voiduserNode:
:
setName(conststring&name)
{
this->name=name;
}
voiduserNode:
:
setPassword(conststring&password)
{
this->password=password;
}
stringuserNode:
:
getName()
{
returnname;
}
stringuserNode:
:
getPassword()
{
returnpassword;
}
intuserNode:
:
getHeight()
{
returnthis==NULL?
-1:
height;
}
voiduserNode:
:
changeHeight(constinth)
{
height=h;
}
booluserNode:
:
checkName(conststring&name)
{
if(this->name==name)returntrue;
elsereturnfalse;
}
userNode:
:
userNode(conststring&name,conststring&password)
{
this->name=name;
this->password=password;
height=O;
left=NULL;
right=NULL;
}
userNode:
:
userNode(constuserNode&temp)
{
this->name=temp.name;
this->password=temp.password;
height=0;
left=NULL;
right=NULL;
}
Tree.cpp
#include"tree.h"
#include
//构造函数
tree:
:
tree()
{
root=NULL;
}
voidtree:
:
insert_node(userNode&temp)
{
insert_node(root,temp);
}
voidtree:
:
insert_node(userNode*&r,userNode&t)
{
if(r==NULL)
{
r=newuserNode(t);//若树为空,直接新建节点
}
elseif(r->getName()==t.getName())//若节点值相等,则用户名重复
{
return;
stringrename;
cout«"用?
户§名?
"vvt.getName()v<"已?
经-存?
在",?
请?
修T改?
"< t.setName(rename); insert_node(r,t); elseif(r->getName()>t.getName()) { insert_node(r->left,t); if(r->left->getHeight()-r->right->getHeight()==2) { rightBalance(r); } } elseif(r->getName() { insert_node(r->right,t); if(r->right->getHeight()-r->left->getHeight()==2){ leftBalance(r); } r->changeHeight(max(r->left->getHeight(),r->right->getHeight())+1); } //移除 voidtree: : remove(userNode*&r,userNode*&temp) { if(r==NULL) { return; } elseif(temp->getName() { remove(r->left,temp); if(r->right->getHeight()-r->left->getHeight()==2)leftBalance(r); } elseif(temp->getName()>r->getName()) { remove(r->right,temp); if(r->left->getHeight()-r->right->getHeight()==2)rightBalance(r); } else { if(r->left==NULL) { userNode*q=r; r=r->right; deleteq; } elseif(r->right==NULL) { userNode*q=r; r=r->left; deleteq; } else{ userNode*R; r=searchLeftMaxNode(r,R); remove(r->left,R); if(r->right->getHeight()-r->left->getHeight()==2)leftBalance(r); } } if(r) r->changeHeight(max(r->left->getHeight(),r->right->getHeight())+1); } voidtree: : remove(userNode*&temp) { remove(root,temp); } voidtree: : print() { print(0,root); } voidtree: : print(intindex,userNode*r) { if(r) { print(index+8,r->right); cout< print(index+8,r->left); } } voidtree: : Print(ofstream&ofile,userNode*&r) { if(r) { Print(ofile,r->left); ofile< Print(ofile,r->right); } } voidtree: : Print() { userNode*p=root; ofstreamofile; ofile.open("user.txt"); assert(ofile.is_open()); Print(ofile,p); ofile.close(); } voidtree: : rotateL(userNode*&r) { userNode*R=r->right; r->right=R->left; R->left=r; r->changeHeight(max(r->left->getHeight(),r->right->getHeight())+1); R->changeHeight(max(R->left->getHeight(),r->getHeight())+1); r=R; } voidtree: : rotateR(userNode*&r) { userNode*L=r->left; r->left=L->right; L_>right=r; r->changeHeight(max(r->left->getHeight(),r->right->getHeight())+1); L->changeHeight(max(L->left->getHeight(),r->getHeight())+1); r=L; } voidtree: : rotateDoubleLR(userNode*&r) { rotateL(r->left); rotateR(r); } voidtree: : rotateDoubleRL(userNode*&r) { rotateR(r->right); rotateL(r); } voidtree: : rightBalance(userNode*&r) { userNode*temp=r->left; if(temp->left->getHeight()-temp->right->getHeight()==-1)rotateDoubleLR(r); elserotateR(r); } voidtree: : leftBalance(userNode*&r) { userNode*temp=r->right; if(temp->left->getHeight()-temp->right->getHeight()==1)rotateDoubleRL(r); elserotateL(r); } userNode*tree: : findNode(strings) { userNode*r=root; while(r) { if(s==r->getName()) returnr; elseif(s r=r->left; elseif(s>r->getN
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 用户 登录 系统