用户登录系统.docx

上传人:b****7 文档编号:10030488 上传时间:2023-02-08 格式:DOCX 页数:31 大小:237.05KB
下载 相关 举报
用户登录系统.docx_第1页
第1页 / 共31页
用户登录系统.docx_第2页
第2页 / 共31页
用户登录系统.docx_第3页
第3页 / 共31页
用户登录系统.docx_第4页
第4页 / 共31页
用户登录系统.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

用户登录系统.docx

《用户登录系统.docx》由会员分享,可在线阅读,更多相关《用户登录系统.docx(31页珍藏版)》请在冰豆网上搜索。

用户登录系统.docx

用户登录系统

数据结构大型实验

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

#ineludeusingnamespaeestd;

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()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<getName()v<"("<left->getHeight()-r->right->getHeight()<<)"<

print(index+8,r->left);

}

}

voidtree:

:

Print(ofstream&ofile,userNode*&r)

{

if(r)

{

Print(ofile,r->left);

ofile<getName()<<","<getPassword()<<'\n';

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(sgetName())

r=r->left;

elseif(s>r->getN

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1