1. 程式人生 > >2017大二學年 數據結構課程設計-校園十大優秀青年評比

2017大二學年 數據結構課程設計-校園十大優秀青年評比

編號 account pre 通過 ticket 軟件 位置為空 函數 else

南 通 大 學

數據結構課程設計報告

名:

級:

物聯網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大二學年 數據結構課程設計-校園十大優秀青年評比