模板实现排行榜管理.docx
《模板实现排行榜管理.docx》由会员分享,可在线阅读,更多相关《模板实现排行榜管理.docx(39页珍藏版)》请在冰豆网上搜索。
![模板实现排行榜管理.docx](https://file1.bdocx.com/fileroot1/2023-7/10/4bd3c7b4-d3b0-449f-87f9-aa8509401abc/4bd3c7b4-d3b0-449f-87f9-aa8509401abc1.gif)
模板实现排行榜管理
南京理工大学
VC++课程设计报告
课程:
测控技术与仪器
系别:
测控技术与仪器
班级:
9141011701
学号:
************
*******
选题名称:
模板实现排行榜管理
模板实现排行榜管理
1.程序功能简介
模板形式的二叉树操作的实现。
定义了二叉树的一些基本功能:
插入、查找、删除子树、前序、中序、及后序遍历等。
2.程序设计说明
(1)、模板类型用排行榜数据替代,建立一棵二叉树,表示游戏挑战大赛积分排行榜;当出现一个挑战者,其成绩能加到数据库中;也可将弃权者的记录从数据库中删除。
思路:
记录包含这两个内容,一是姓名,二是成绩,所以我用两个二叉树分别记录姓名与成绩,一个根据姓名顺序构造二叉树,一个根据数据构造二叉树。
(2)、能显示分数排行榜,能根据姓名的顺序显示分数。
思路:
只要将大的数排在右子数,小的数排在左子树,输出时从左到右输出就能轻松解决了。
(3)、统计平均得分
思路:
设置全局静态量,记录输入的数据个数,记录输入的数据和。
(4)、根据人名查找分数
(5)、根据分数查找人名
思路:
在构造两个二叉树的情况下,实现(4)、(5)功能还是很容易的。
(6)、修改main函数,可以从键盘输入数据,要求界面清楚并可循环操作。
思路:
在一个操作完成后,只要增加一个询问的语句一个返回的语句就可以轻松实现此功能了。
成绩类二叉树:
classSCORE//成绩类,可以根据成绩构造二叉树
{
private:
charszName[20];//姓名
floatflScore;//成绩
public:
SCORE(){strcpy(szName,"");flScore=0;}//缺省的构造函数
SCORE(char*name,floatscore){strcpy(szName,name);flScore=score;}//构造函数
char*GetName(){returnszName;}//返回姓名,删除姓名类二叉树时使用
intoperator>(SCORE&record);//重载>,实现二叉树的功能时使用
intoperator<(SCORE&record);//重载<,实现二叉树的功能时使用
intoperator==(SCORE&record);//重载==,实现二叉树的功能时使用
friendistream&operator>>(istream&is,SCORE&);//重载输入
friendostream&operator<<(ostream&os,SCORE&);//重载输出
};
姓名类二叉树:
classRecord//姓名类数据,根据姓名的顺序构造二叉树
{
private:
charszName[20];//姓名
floatflScore;//成绩
public:
Record(){strcpy(szName,"");flScore=0;}//缺省的构造函数
Record(char*name,floatscore){strcpy(szName,name);flScore=score;}
//构造函数
floatGetScore(){returnflScore;}//返回成绩,删除成绩类二叉树时使用
intoperator>(Record&record);//重载>,实现二叉树的功能时使用
intoperator<(Record&record);//重载<,实现二叉树的功能时使用
intoperator==(Record&record);//重载==,实现二叉树的功能时使用
friendistream&operator>>(istream&is,Record&);//重载输入
friendostream&operator<<(ostream&os,Record&);//重载输出
};
******************************************************************************
insertNode(Tdata)//插入新结点
{
TreeNode*newNode=newTreeNode;//新建结点
TreeNode*nodePtr;
newNode->data=data;//结点赋值
newNode->left=newNode->right=NULL;
if(!
root)
root=newNode;//唯一结点
else
{
nodePtr=root;
while(nodePtr!
=NULL)//循环查找,将结点输入树中
{
if(newNode->datadata)
{
if(nodePtr->left)
nodePtr=nodePtr->left;
else
{
nodePtr->left=newNode;
break;
}
}
elseif(newNode->data>nodePtr->data)
{
if(nodePtr->right)
nodePtr=nodePtr->right;
else
{
nodePtr->right=newNode;
break;
}
}
else
{
cout<<"Duplicatevalue("<break;
}
}
}
(1)、删除结点(根据姓名或数据)
注:
在删除时要同时删除两个双向链表的结点,在根据姓名(成绩)删除时,在姓名(成绩)二叉树中根据姓名找出成绩(姓名),然后在成绩(姓名)二叉树中删除记录,
voidDelete(TREESTRUCT&mytree,TREESTRUCT&myscore,intCHOICE)
//根据姓名或成绩删除结点
{
TreeNode*tree;
TreeNode*score;
Record*rec;
SCORE*sco;
charchoice;
floatflscore;
charname[20];
switch(CHOICE)
{
case2:
do{
cout<<"请输入欲删除结点的姓名:
";
cin>>name;
rec=newRecord(name,0);//生成姓名类二叉树的结点数据
if(tree=mytree.searchNodes(*rec))
{flscore=tree->data.GetScore();
//将树中结点数据的成绩读出
mytree.remove(*rec);//删除姓名类二叉树结点
sco=newSCORE("",flscore);
//根据读出的成绩生成成绩类二叉树的结点数据
myscore.remove(*sco);//删除成绩类二叉树结点
}
else
cout<<"该结点不存在!
\n";
cout<<"是否继续(y/n)?
";
cin>>choice;
cin.ignore();
}while(choice=='y'||choice=='Y');
break;
case5:
do{
cout<<"请输入欲删除结点的成绩:
";
cin>>flscore;
sco=newSCORE("",flscore);//生成成绩类二叉树的结点数据
if(score=myscore.searchNodes(*sco))
{strcpy(name,score->data.GetName());
//将树中结点数据的姓名读出
myscore.remove(*sco);//删除成绩类二叉树结点
rec=newRecord(name,0);
//根据读出的姓名生成姓名类二叉树的结点数据
mytree.remove(*rec);//删除姓名类二叉树结点
}
else
cout<<"该结点不存在!
\n";
cout<<"是否继续(y/n)?
";
cin>>choice;
cin.ignore();
}while(choice=='y'||choice=='Y');
break;
}
}
***************************************************************************
(2)、能显示分数的排行榜,能根据姓名的顺序显示分数。
showNodesInOrder(TreeNode*tRoot)//根据结点顺序显示二叉树
{
if(tRoot==NULL)
{
//cout<<"二叉树为空,无法排序!
";
return;
}
showNodesInOrder(tRoot->left);
cout<data<showNodesInOrder(tRoot->right);
}
(3)、根据人名查找分数;根据分数查找人名。
TREESTRUCT:
:
searchNodes(Tsearch)//查找结点,返回结点指针
{
TreeNode*tRoot=root;
if(tRoot==NULL)
return0;
if(tRoot->data==search)
returntRoot;
while(tRoot!
=NULL)
{
if(searchdata)
tRoot=tRoot->left;
elseif(search>tRoot->data)
tRoot=tRoot->right;
elseif(search==tRoot->data)
returntRoot;
else
//cout<<"不存在该结点!
";
return0;
}
return0;
}
do{
cout<<"请输入欲查找结点的姓名:
";
cin>>name;
rec=newRecord(name,0);//生成姓名类二叉树的结点数据
tree=mytree.searchNodes(*rec);
mytree.showNode(tree);
cout<<"是否继续(y/n)?
";
cin>>choice;
cin.ignore();
}while(choice=='y'||choice=='Y');
break;
do{
cout<<"请输入欲查找结点的成绩:
";
cin>>flscore;
sco=newSCORE("",flscore);//生成成绩类二叉树的结点数据
score=myscore.searchNodes(*sco);
myscore.showNode(score);
cout<<"是否继续(y/n)?
";
cin>>choice;
cin.ignore();
}while(choice=='y'||choice=='Y');
break;
(4)、计算平均数
staticfloatm=0;//定义静态全局变量,用于计算总成绩
staticintn=0;//定义静态全局变量,用于计算总人数
//用于计算平均数
当插入一个结点就加到m上,人数n自加一次;当删除一个结点时,就从m中减去,人数n自减一次。
最后输出m/n,就为平均数。
(5)、变量说明
staticfloatm=0;//定义静态全局变量,用于计算总成绩
staticintn=0;//定义静态全局变量,用于计算总人数
//用于计算平均数
TREESTRUCTmytree;//建立姓名类型数据的二叉树
TREESTRUCTmyscore;//建立成绩类型数据的二叉树
TreeNode*tree;//指向姓名类
TreeNode*score;//指向成绩类
Record*rec;//定义姓名类指针对象
SCORE*sco;//定义成绩类指针对象
floatflscore;//成绩
charname[20];//姓名
**************************************************************************
char*change(char*oldname)//创新,进一步改进
//将输入字符状串转换成小写,以便按顺序存放
{
inti;
for(i=0;oldname[i]!
='\0';i++)
{oldname[i]=tolower(oldname[i]);}
returnoldname;
}
3.测试程序的过程
(1)、程序在编译时出现错误,经过与老师的讨论,调整二叉树的数据结构等,比如,对于计算总数据记录数的个数,通过设置全局变量,可以有效的解决“n”重复定义的情况。
(2)、在调试过程:
对于在if语句中,有些大于号,小于号出现问题,最终使设计的程序与目标程序相差甚远,经过仔细观察,思考,发现了问题。
经过与同学的讨论,上网查找答案,最终得到了解决方案。
4.输入输出
5.设计心总结
课程设计在一开始的时候感觉比较困难,二叉树我并不熟悉,不过在看了书本上的源程序后,觉得二叉树我虽然没有学过,但基本的思想实际上却是数的一种排列方式,一种更有利于排序等操作的排序方式,根据课本的提示,我发现成员函数并不需要改变,之需要增加两个链表就能解决这个问题,我参考了许多书本,网络上的案例,编写出了这个程序。
虽然我只完成了这个程序的很小一部分,但当程序编译没有错误的那一个,着实兴奋了不久,又经过了调试,发现虽然大致上能用,但仍有不少错误。
我一开始对这大规模的程序感到厌倦,但随着编程的进行,也感受到了编程蕴含着的魅力。
存在问题:
不能输入两个人相同的分数,否则会出现错误。
在查找、删除时只能找到第一次输进去人的姓名,在某些情况下输入字母‘N’或‘n’会使同一个记录不断输出。
5.附录:
程序
#include
#include
#include
//
staticfloatm=0;//定义静态全局变量,用于计算总成绩
staticintn=0;//定义静态全局变量,用于计算总人数
//用于计算平均数
//
template
structTreeNode
{
TreeNode*right;
TreeNode*left;
Tdata;
};
//****************************************************************************
classSCORE//成绩类,可以根据成绩构造二叉树
{
private:
charszName[20];//姓名
floatflScore;//成绩
public:
SCORE(){strcpy(szName,"");flScore=0;}//缺省的构造函数
SCORE(char*name,floatscore){strcpy(szName,name);flScore=score;}//构造函数
char*GetName(){returnszName;}//返回姓名,删除姓名类二叉树时使用
intoperator>(SCORE&record);//重载>,实现二叉树的功能时使用
intoperator<(SCORE&record);//重载<,实现二叉树的功能时使用
intoperator==(SCORE&record);//重载==,实现二叉树的功能时使用
friendistream&operator>>(istream&is,SCORE&);//重载输入
friendostream&operator<<(ostream&os,SCORE&);//重载输出
};
/**********************************************************************************/
intSCORE:
:
operator>(SCORE&record)//重载>,实现二叉树的功能时使用
{
if(flScore>record.flScore)return1;
elsereturn0;
}
//
intSCORE:
:
operator<(SCORE&record)//重载<,实现二叉树的功能时使用
{
if(flScoreelsereturn0;
}
//
intSCORE:
:
operator==(SCORE&record)//重载==,实现二叉树的功能时使用
{
if(flScore==record.flScore)return1;
elsereturn0;
}
//
istream&operator>>(istream&is,SCORE&record)//重载输入
{
is>>record.flScore;
returnis;
}
//
ostream&operator<<(ostream&os,SCORE&record)//重载输出
{
os<returnos;
}
//****************************************************************************
classRecord//姓名类数据,根据姓名的顺序构造二叉树
{
private:
charszName[20];//姓名
floatflScore;//成绩
public:
Record(){strcpy(szName,"");flScore=0;}//缺省的构造函数
Record(char*name,floatscore){strcpy(szName,name);flScore=score;}
//构造函数
floatGetScore(){returnflScore;}//返回成绩,删除成绩类二叉树时使用
intoperator>(Record&record);//重载>,实现二叉树的功能时使用
intoperator<(Record&record);//重载<,实现二叉树的功能时使用
intoperator==(Record&record);//重载==,实现二叉树的功能时使用
friendistream&operator>>(istream&is,Record&);//重载输入
friendostream&operator<<(ostream&os,Record&);//重载输出
};
/********************************************************************************/
intRecord:
:
operator>(Record&record)//重载>,实现二叉树的功能时使用
{
if(strcmp(szName,record.szName)>0)return1;
elsereturn0;
}
//
intRecord:
:
operator<(Record&record)//重载<,实现二叉树的功能时使用
{
if(strcmp(szName,record.szName)<0)return1;
elsereturn0;
}
//
intRecord:
:
operator==(Record&record)//重载==,实现二叉树的功能时使用
{
if(strcmp(szName,record.szName)==0)return1;
elsereturn0;
}
//
istream&operator>>(istream&is,Record&record)//重载输入
{
is>>record.szName;
returnis;
}
//
ostream&operator<<(ostream&os,Record&record)//重载输出
{
os<returnos;
}
//*************************************************************************
template
classTREESTRUCT
{
public:
TREESTRUCT(){root=NULL;}//缺省的构造函数
~TREESTRUCT()
{makeDeleteSubTree(root);root=NULL;}//析构函数,将