AVL树模拟用户登录系统的实验报告附代码和详尽注释 2.docx

上传人:b****7 文档编号:23735627 上传时间:2023-05-20 格式:DOCX 页数:53 大小:192.42KB
下载 相关 举报
AVL树模拟用户登录系统的实验报告附代码和详尽注释 2.docx_第1页
第1页 / 共53页
AVL树模拟用户登录系统的实验报告附代码和详尽注释 2.docx_第2页
第2页 / 共53页
AVL树模拟用户登录系统的实验报告附代码和详尽注释 2.docx_第3页
第3页 / 共53页
AVL树模拟用户登录系统的实验报告附代码和详尽注释 2.docx_第4页
第4页 / 共53页
AVL树模拟用户登录系统的实验报告附代码和详尽注释 2.docx_第5页
第5页 / 共53页
点击查看更多>>
下载资源
资源描述

AVL树模拟用户登录系统的实验报告附代码和详尽注释 2.docx

《AVL树模拟用户登录系统的实验报告附代码和详尽注释 2.docx》由会员分享,可在线阅读,更多相关《AVL树模拟用户登录系统的实验报告附代码和详尽注释 2.docx(53页珍藏版)》请在冰豆网上搜索。

AVL树模拟用户登录系统的实验报告附代码和详尽注释 2.docx

AVL树模拟用户登录系统的实验报告附代码和详尽注释2

 

一.实验内容分析:

1.实验目的:

模拟用户登录系统,在O(lgn)时间内完成用户登录、删除、修改等工作。

2.设计思路:

主要分以下四个类:

AVLTreeNode:

存储平衡树节点;

AVLTree:

AVL平衡树的主要实现算法;

UserInfo:

存储用户信息;

Interface:

界面,与用户交互;

3.

流程图以及类的主要包含和调用关系:

二.实验验证分析

(1)输入的形式和输入值的范围;

控制台的输入:

如图,输入为数字,超出范围将提示不正确并返回重新输入

文件的输入:

程序会找寻当前目录的database.data文件,并读入数据,如果未找到则自创此文件,创建空树

(2)输出的形式;

程序退出时析构函数保存文件到database.data并覆盖原文件。

(3)程序所能达到的功能;

在O(lgn)时间内添加、查找、删除、修改用户信息。

(4)测试数据:

本系统包含三个测试函数样例:

1.顺序插入测试(分别在debug和release环境下和STLmap比较速度)

2.随机插入测试(分别在debug和release环境下和STLmap比较速度)

3.删除测试

测试函数均在main文件里

voidrandomTest();//随机数测试

voidorderTest();//顺序插入测试

voiddeleteTest();//删除测试

voidmain_interface();//主界面

1,2均在debug模式下插入100W数据,在release模式下插入1000W数据。

顺序插入的实现是用整数1~n转换为string,位数不够的在前面补‘0’。

 

测试结果:

1.debug下顺序插入测试:

2.Release下顺序插入测试

 

3.debug下随机插入测试

4.release下随机插入测试

实践证明map的红黑树在顺序插入测试时慢于我的avl树,但随机插入测试表现比AVL树要好。

3.删除数据的图形化表示(‘R’‘L’‘=’为平衡因子以检验正确性)

下面删除3(树中无3):

还是一样,下面删除2

删除成功,下面删除7

删除成功。

三.调试分析

(1)讨论分析调试过程中的主要技术问题以及具体的解决方法(至少3个);

1.代码重复问题:

有重复的代码不是好代码。

左右旋和左旋右旋有大量重复,经过分析发现左右旋可以分解为先左旋后右旋,但平衡因子调整方法不一。

所以分解左旋和右旋为两个函数,调整平衡因子单分一个函数。

2.空间占用问题:

平衡因子只有3个取值却占了一个int4个字节是极大的浪费,所以改用char型。

编程实践中发现树高也可以取消,也极大的节省了空间。

3.时间浪费问题:

先调整平衡因子再旋转最后再调整平衡因子浪费时间,经分析后可以采取一些代码上的改动而将第一次调整省略。

(2)技术难点分析(至少3个);

1.由于放弃树高调整平衡因子,所以平衡因子的调整是编程最困难之处,采用方法是根据插入子数是左子树还是右子树调整父亲的平衡因子。

2.删除时需先采用BST的删除方式,再分情况用类似AVL插入节点时的调整方法,必须完全搞懂BST和AVL才能正确地处理删除问题。

3.代码阅读问题:

纯算法程序一般难以阅读,尤其是像AVL这类复杂算法,即使是自己也是编了前面忘了后面,所以程序添加了海量的注释,每个函数每个重要语句都有功能解说,代码命名取其意思,格式遵循《cleanCode》。

(3)印象最深刻的3个调试错误,及修正方法;

1.最深的当然是访问了没初始化的内存!

几乎90%调试问题都与此有关。

大部分非法访问内存经调试都归结于平衡因子的错误。

解决方法是在纸上画出几个正确的例子,再输入进程序调试,看平衡因子的错误具体地址和引起其错误的代码。

反复调试修改直到测试再大数据量也不会报错。

2.链接错误。

好像是1005,此错误的原因是.h文件内除了成员函数不能有其它函数。

原来是我用的友元重载比较函数(必须用友元,否则类对象比较时重载不匹配。

)网上查了好半天才知道的原因。

解决方法:

友元重载比较运算符函数放到.cpp文件里。

3.头文件包含问题要彻底搞明白,.h文件必须加头文件卫士,.cpp必须不加而且不能被#include,。

4.测试结果:

(1)展示程序的运行结果,包括输入和输出,分析数据的正确性;

1.database.data文件(存放用户名密码)

 

2.用户登录

 

3.添加用户

 

 

 

4.删除用户

 

4.更新用户

 

 

(2)应用边界数据、或极端数据测试系统,分析结果的正确性。

实验分析验证里已进行充分测试。

5.附录:

附上源代码,并标明源代码的所属文件,并且源代码必须有注释。

//-----------------------------------------------------------------

//AVLTreeNode.h

//AVL树节点类

//功能:

提供主键、左右子指针、父指针,平衡因子

//说明:

平衡因子为char,节约空间(L相当于1,R相当于-1,=相当于0)

//修改时间:

2013-12-2514:

29:

44

//-----------------------------------------------------------------

#ifndefAVLTreeNode_H

#defineAVLTreeNode_H

#include"UserInfo.h"

classAVLTreeNode

{

public:

UserInfokey;

AVLTreeNode*left;

AVLTreeNode*right;

AVLTreeNode*parent;

charbalanceFactor;

AVLTreeNode()

{

left=0;

right=0;

parent=0;

balanceFactor='=';

}

AVLTreeNode(UserInfos)

{

key=s;

left=0;

right=0;

parent=0;

balanceFactor='=';

}

};

#endif

//==================================================================

//AVLTree.h

//AVL平衡树,实现了添加、查找、图形输出等功能

//Author:

hufeiyaZJUT

//2013-12-414:

38:

04

//2013-12-2414:

35:

42添加了删除方法

//插入经过3KW数据严格测试,删除不严格测试

//==================================================================

#ifndefAVLTree_H

#defineAVLTree_H

#include

#include

#include

#include"AVLTreeNode.h"

usingnamespacestd;

 

classAVLTree

{

private:

public:

AVLTree();

~AVLTree();//析构函数。

调用①

voidinsert(AVLTreeNode*n);//插入元素。

调用④⑤⑥⑦

voidgraph();//图形输入。

调用②

voidinOrder(ofstream&fs);//中序遍历修改文件。

调用③

AVLTreeNode*find(UserInfotarget);//查找元素,返回地址。

voidremove(UserInfokey);//删除元素。

调用⑥⑦⑧⑨

private:

AVLTreeNode*root;

voidClearTree(AVLTreeNode*n);//清除所有元素①

voidgraphAux(AVLTreeNode*subtree,inta);//递归图形输出②

voidinOrderAux(ofstream&fs,AVLTreeNode*subtree);//递归中序遍历③

voidrestoreAVL(AVLTreeNode*ancestor,AVLTreeNode*newNode);//添加节点后重建树④

voidadjustBalanceFactors(AVLTreeNode*end,AVLTreeNode*start);//调整平衡因子(插入时)⑤

voidrotateLeft(AVLTreeNode*n);//左旋,插入删除共用⑥

voidrotateRight(AVLTreeNode*n);//右旋,插入删除共用⑦

voidsearch2(constUserInfo&data,bool&found,AVLTreeNode*&x,AVLTreeNode*&parent);//remove辅助函数⑧

voidrestoreAVL2(AVLTreeNode*start,boolleft);//删除节点后后重建树⑨

};

#endif

//-----------------------------------------------------------------

//Interface.h

//界面类

//功能:

构建界面、读取和写入文件

//修改时间:

2013-12-2514:

27:

17

//-----------------------------------------------------------------

#ifndefInterface_H

#defineInterface_H

#include

#include

#include

#include

#include"AVLTree.h"

usingnamespacestd;

classInterface

{

public:

Interface();//构造函数,读取文件,创建并建立树

~Interface();//保存信息到文件,销毁树,关闭文件

voidmainFace();

voidlogIn();

voidaddUser();

voidremoveUser();

voidupdate();

private:

AVLTree*data;

ifstreamreadStream;

ofstreamwriteStream;

};

 

#endif

//-----------------------------------------------------------------

//UserInfo.h

//用户信息类

//功能:

储存用户名、密码等信息,重载部分操作符

//修改时间:

2013-12-2514:

26:

05

//-----------------------------------------------------------------

#ifndefUserInfo_H

#defineUserInfo_H

#include

#include

usingnamespacestd;

classUserInfo

{

public:

UserInfo(){}

UserInfo(stringname,stringpass);

UserInfo(stringname);//缺省密码等于账号

UserInfo(char*name);//缺省密码等于账号

UserInfo(constUserInfo&b);//复制构造函数

friendbooloperator<(constUserInfo&a,constUserInfo&b);

friendbooloperator>(constUserInfo&a,constUserInfo&b);

booloperator==(constUserInfo&b);

friendostream&operator<<(ostream&os,constUserInfo&b);

friendclassInterface;

friendclassAVLTree;

private:

stringusername;

stringpassword;

};

 

#endif

下面是.cpp文件

Main.cpp:

#include"AVLTree.h"

#include

#include

#include

#include

#include

#include

#include"Interface.h"

#pragmawarning(disable:

4996)

usingnamespacestd;

#defineMAX10000000

stringa[MAX];

AVLTreeNode*p[MAX];

voidrandomTest();//随机数测试

voidorderTest();//顺序插入测试

voiddeleteTest();//删除测试

voidmain_interface();//主界面

intmain()

{

//orderTest();

//randomTest();

//deleteTest();

main_interface();

return0;

}

voiddeleteTest()

{

AVLTree&a=*newAVLTree();

AVLTreeNode*p=newAVLTreeNode("4");

a.insert(p);

p=newAVLTreeNode("15");

a.insert(p);

p=newAVLTreeNode("21");

a.insert(p);

p=newAVLTreeNode("38");

a.insert(p);

p=newAVLTreeNode("14");

a.insert(p);

p=newAVLTreeNode("18");

a.insert(p);

p=newAVLTreeNode("28");

a.insert(p);

p=newAVLTreeNode("6");

a.insert(p);

p=newAVLTreeNode("5");

a.insert(p);

p=newAVLTreeNode("7");

a.insert(p);

p=newAVLTreeNode("1");

a.insert(p);

p=newAVLTreeNode("2");

a.insert(p);

p=newAVLTreeNode("100");

a.insert(p);

p=newAVLTreeNode("8");

a.insert(p);

a.graph();

a.remove("3");

a.graph();

a.remove("2");

a.graph();

a.remove("7");

a.graph();

delete&a;

}

voidrandomTest()

{

//freopen("G:

\\1.txt","w",stdout);

AVLTree&at=*newAVLTree();

ints=0;

stringstreamss;

mapstlMap;

srand((int)time(0));

for(inti=0;i

{

ss<

ss>>a[i];

p[i]=newAVLTreeNode(a[i]);

ss.clear();

}

cout<<"随机字符串生成完毕,现在插入到AVL树\n";

doubleoldTime=clock(),newTime;

while(s

{

at.insert(p[s]);

s++;

//cout<

}

//at.graph();

newTime=clock()-oldTime;

cout<<"写入"<

cout<<"现在测试STLmap,写入相同字符串集合\n";

oldTime=clock();

for(inti=0;i

{

stlMap[a[i]]++;

}

newTime=clock()-oldTime;

cout<<"写入"<

cout<<"请输入要查找的数\n";

stringtempName;

AVLTreeNode*address=0;

while(cin>>tempName)

{

UserInfotempUser(tempName);

oldTime=clock();

address=at.find(tempUser);

if(0!

=address)

cout<<"已找到,在地址为"<

else

cout<<"未找到\n";

newTime=clock()-oldTime;

cout<<"查找共用时"<

}

delete&at;

}

voidorderTest()

{

//freopen("G:

\\1.txt","w",stdout);

AVLTree&at=*newAVLTree();

ints=0;

stringstreamss;

mapstlMap;

inttemp;

stringzeroNum[]={"","0","00","000","0000","00000","000000","0000000","00000000","000000000",};

srand((int)time(0));

for(inti=1;i

{

stringtempZero;

intnum=0;

for(intj=i;j

{

num+=1;

}

ss<

stringtemp1;

ss>>temp1;

tempZero+=zeroNum[num];

tempZero+=temp1;

a[i]=tempZero;

p[i]=newAVLTreeNode(a[i]);

ss.clear();

}

cout<<"顺序字符串生成完毕,现在插入到AVL树\n";

doubleoldTime=clock(),newTime;

while(s

{

at.insert(p[s]);

s++;

//cout<

}

//at.graph();

newTime=clock()-oldTime;

cout<<"写入"<

cout<<"现在测试STLmap,写入相同字符串集合\n";

oldTime=clock();

for(inti=0;i

{

stlMap[a[i]]++;

}

newTime=clock()-oldTime;

cout<<"写入"<

cout<<"请输入要查找的数\n";

stringtempName;

AVLTreeNode*address=0;

while(cin>>tempName)

{

UserInfotempUser(tempName);

oldTime=clock();

address=at.find(tempUser);

if(0!

=address)

cout<<"已找到,在地址为"<

else

cout<<"未找到\n";

newTime=clock()-oldTime;

cout<<"查找共用时"<

}

delete&at;

}

voidmain_interface()

{

Interface&test=*newInterface();

delete&test;

}

UserInfo.cpp

#include"UserInfo.h"

UserInfo:

:

UserInfo(stringname,stringpass)

{

username=name;

password=pass;

}

UserInfo:

:

UserInfo(stringname)

{

username=name;

password=name;

}

UserInfo:

:

UserInfo(char*name)

{

username=name;

password=name;

}

UserInfo:

:

UserInfo(constUserInfo&b)//复制构造函数

{

username=b.username;

password=b.password;

}

booloperator<(constUserInfo&a,constUserInfo&b)

{

returna.username

}

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

当前位置:首页 > 经管营销 > 人力资源管理

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

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