2017大二學年 數據結構課程設計-校園十大優秀青年評比
南 通 大 學
數據結構課程設計報告
姓 名: |
|
班 級: |
物聯網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、顯示所剩可投票數
2017大二學年 數據結構課程設計-校園十大優秀青年評比