南 通 大 学
数据结构课程设计报告
姓 名: | |
班 级: | 物联网162 |
学 号: |
|
指导老师: | 杭月琴 |
选 题: | 校园十大优秀青年评比 |
日 期: | 2018/1/18 |
计算机科学与技术学院
实验校园十大优秀青年评比
1,问题描述
新一届校园十大优秀青年评比开始了!每一位在校学生可通过网上评比系统,为自己认为优秀的学生提名与投票。请开发一个用于该需求的系统,满足下列基本功能。
(1)提名优秀学生和投票。
(2)查看提名学生的基本信息。
(3)显示各提名学生的票数。
(4)显示排行榜
2.数据结构设计
//账户结构体
struct account{
string loginname;
string password;
int cast; //可投票数
};
//学生结构体
struct Student{
string name; //学生姓名
int number; //学号
int ticket; //票数
string mclass; //班级名
string major; //专业
string grade; //年级
string achievement; //突出事迹
};
//哈希表单元
struct elem{
int flag; //若存储有值则为1,否则为0
Student * stu;
};
//树节点
struct Node{
Node * lchild;
Node * rchild;
Student * stu;
};
3..算法设计
本程序设计的算法有: 登录、注册、提名学生、投票、显示所有提名学生信息、显示排行榜、检测所剩可投票数
(1) 登录
int match()//匹配账号密码是否正确,成功返回账号的编号,否则返回-1
{
string loginname, password;
cin >> loginname >> password;
for (int i = 0; i<n; i++)
{
if (loginname == LA[i].loginname&&password == LA[i].password)
return i;
}
return -1;
}
(2) 注册
int regist() //注册;如果账号名重复,则返回0,否则加入账号数组中
{
string loginname, password;
cout << "请输入你的手机号和密码:" << endl;
cin >> loginname >> password;
int i;
for (i = 0; i<n&&loginname != LA[i].loginname; i++); //循环判断是否账号重复
if (i<n) return 0;
LA[n].loginname = loginname;
LA[n].password = password;
LA[n].cast = castnum;
n++;
return 1;
}
(3) 提名学生
//哈希函数是i=num%97
void store() //存储提名学生
{
int loc, i;
string name; //学生姓名
int number; //学号
string mclass; //班级名
string major; //专业
string grade; //年级
string achievement;
cout << "请依次输入你要提名的学生的姓名、学号、班级名称、专业、年级、成就:" << endl;
cin >> name >> number >> mclass >> major >> grade >> achievement;
loc = number%key; //哈希函数
for (i = 0;loc+i<MAX&&stuList[loc + i].flag; i++); //线性探测直到当哈希表存储位置为空
stuList[loc + i].stu = new Student();
stuList[loc + i].flag = 1;
stuList[loc + i].stu->name = name;
stuList[loc + i].stu->number = number;
stuList[loc + i].stu->mclass = mclass;
stuList[loc + i].stu->major = major;
stuList[loc + i].stu->grade = grade;
stuList[loc + i].stu->achievement = achievement;
stuList[loc + i].stu->ticket = 0;
nstu++; //提名人数+1
cout << "提名成功!" << endl;
}
(4) 投票
//首先根据学号找到被投票学生被存放的地址
int findstu() //若找到学生则返回其所在地址,否则返回哈希表长度
{
int num, locate;
cin >> num;
for (locate = num%key; num != stuList[locate].stu->number; locate++);
return locate;
}
//先检测该投票人是否还有选票,如果有选票在找到该学生被存放的地址后,将其票数+1,没有选票则不能进行投票
void vote(int acc) //投票函数 参数为登录账户编号
{
if (LA[acc].cast>0)
{
cout << "请输入你要投票的学生学号:" << endl;
int locate = findstu();
stuList[locate].stu->ticket++;
cout << "为小哥哥疯狂打call成功!你还剩" << --LA[acc].cast << "张选票!" << endl;
}
else{
cout << "你的选票已经没有喽,不能给小哥哥投票了(!-!)" << endl;
}
}
(5) 全部显示提名学生
//提取出一个打印单个学生信息的函数
void print(Student* stu)
{
cout << "姓名: " <<stu->name << "\n"
<< "学号: " << stu->number << "\n"
<< "票数: " << stu->ticket << "\n"
<< "班级: " << stu->mclass << "\n"
<< "专业: " << stu->major << "\n"
<< "年级:" << stu->grade << "\n"
<< "成就:" << stu->achievement << "\n";
cout << "*******************************************************\n";
}
//打印全部的学生信息
void allPrint()
{
for (int i = 0; i<MAX; i++)
{
if (stuList[i].flag)
{
print(stuList[i].stu);
}
}
}
(6) 排行榜
排行榜使用二叉排序树进行排序,但因为排行榜是从高往低排序,所以将较大数据放在左孩子,较小数据放在右孩子,这样在进行中续遍历时就是递增输出。
//插入一个节点
void insertNode(Node * root, Student * stu)
{
Node * p = root,*f = new Node();
while (p)
{
f = p;
if (p->stu->ticket <= stu->ticket)
{
p = p->lchild;
}
else{
p = p->rchild;
}
}
p = new Node();
p->stu = stu;
p->lchild = p->rchild = NULL;
if (f->stu->ticket <= p->stu->ticket)
{
f->lchild = p;
}
else
f->rchild = p;
}
//创建一个二叉排序树
void Create(Node * root)
{
root->lchild = root->rchild = NULL;
root->stu = NULL;
for (int i = 0; i < MAX; i++)
{
if (stuList[i].flag)
{
if (root->stu == NULL)
{
root->stu = stuList[i].stu;
}else
insertNode(root, stuList[i].stu);
}
}
}
//中序遍历前十个数据
void minprint(Node * root,int sign)
{
if (root == NULL)
return ;
if (sign < 10)
{
minprint(root->lchild,sign);
print(root->stu); sign++;
minprint(root->rchild,sign);
}
}
(7) 检测登陆
int examine(int acc)
{
if (acc == -1)
{
cout << "你还没有登录哦,请先登录再进行操作!" << endl;
return 0;
}
return 1;
}
(8) 打印主菜单
void menu()
{
cout << "---------欢迎来到校园十大优秀青年评比!快为你喜欢的小哥哥小姐姐投上一票吧!----------\n"
<<"----------------------------登录------------------------------------------------\n"
<< "-----------------------------2、注册------------------------------------------------\n"
<< "-----------------------------3、提名------------------------------------------------\n"
<< "-----------------------------4、投票------------------------------------------------\n"
<< "-----------------------------5、查看所有选手信息------------------------------------\n"
<< "-----------------------------6、查看排行榜------------------------------------------\n"
<< "-----------------------------7、查看我的选票----------------------------------------\n"
<< "-----------------------------8、注销登录--------------------------------------------\n"
<< "-----------------------------9、退出系统--------------------------------------------\n";
}
(9)初始化函数
void initialize()
{
for (int i = 0; i < MAX; i++)
{
stuList[i].flag = 0;
}
}
(10)主函数
int main()
{
initialize();
int order;
int acc = -1;
Node * root = new Node();
while (true)
{
menu();
cout << "请输入指令:" << endl;
cin >> order;
switch (order)
{
case 1://登录
{
cout << "请依次输入你的账号和密码:" << endl;
acc = match();
if (acc != -1)
cout << "登陆成功!" << endl;
break;
}
case 2://注册
{
if (regist())
{
cout << "注册成功,快去登录吧!" << endl;
}
else{
cout << "注册失败,账号重复!" << endl;
}
break;
}
case 3: //提名
{
if (examine(acc))
store();
break;
}
case 4://投票
{
if (examine(acc))
vote(acc);
break;
}
case 5: //查看所有选手信息
{
allPrint();
break;
}
case 6: //查看排行榜
{
Create(root);
minprint(root,0);
break;
}
case 7: //查看我的选票
{
if (examine(acc))
cout <<"你还剩"<< LA[acc].cast<<"张选票"<< endl;
break;
}
case 8://注销登录
{
if (examine(acc))
{
acc = -1;
cout << "已经注销登录!请重新登录" << endl;
}
break;
}
case 9: //退出系统
{
return 0;
}
default:
{
cout << "非法操作,请重新输入指令!" << endl;
break;
}
}
}
return 0;
}
4.运行测试
测试数据
2
666 666
1
666 666
3
李逵 231 水利水电161班 水库专业 大二 国家奖学金,为人淳朴善良
3
张建 222 计算机161班 计算机科学与技术专业 大三 国家励志奖学金,三好学生
3
李超 333 软工162班 软件工程 大一 一等奖学金,三好学生标兵
3
邓超 1124 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
鹿晗 1323 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
邓论 486 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
谢娜 547 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
章子怡 777 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
李丹 654 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
古力娜扎 3045 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
迪丽热巴 555 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
孙俪 345 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
欧阳娜娜 234 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
赛亚超人 486 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
孙悟空 547 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
葫芦娃 777 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
邓紫棋 654 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
黑猫警长 3045 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
蔡特 555 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
汤姆 345 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
杰瑞 234 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
李晨 123 软工161 软件工程 大一 一等奖学金,三好学生标兵
3
比特 1613 喷火131 杂技 大三 曾持续喷火三天三夜
2
111 111
1
111 111
4
555
4
555
4
555
4
345
4
234
8
2
222 222
1
222 222
4
654
4
654
4
777
4
777
4
654
8
2
333
333
1
333
333
4
547
4
486
4
547
4
486
4
547
运行结果
5.调试记录及收获
调试体会:
(1)程序功能的实现,是一点一点的实现的。以下是我写这个程序的思路:
思路:
1、实现登录注册功能 ((分别为各个函数)
(1)、注册时将账号和密码放入数组中,检测数组中是否有同样的key 如果有则不能注册 提示账户已存在,请再次输入
(2)、登录时,输入相应账号和密码 用账号在数组中查询,看是否有账号存在,账号存在则判断密码是否正确,如果密码不对的话,提示密码不正确
2、创建一个结构体 student 将相应的学生属性放入,
3、实现提名学生的功能函数
首先输入学生的学号,并根据学号找到存放该学生的位置,然后cin>>stu[i].value;
(1)、建立一个被提名学生的全局学生数组,
(2)、编写一个查询存储位置的函数,返回值int,名称findsite参数为学号
4、投票的函数
检测该投票者所剩票数,*如果>0,将该登陆者的可投票数-1,并 根据输入的学号调用findsite查询学生信息存储位置,将其票数+1,然后调用打印函数print打印该学生的信息。
*如果<0,则显示,你的票数已经使用完
5、显示全部提名学生信息
遍历打印即可
6、显示排行榜
**以票数做二叉排序树,然后中序遍历输出前十个
7、检测输入的非法数据,如果不是合法数据,则打印,请输入正确的指令
8、显示所剩可投票数