您的位置:首页 > 编程语言 > C语言/C++

程序设计篇(1):学生经验值管理系统(单链表实现)

2016-04-21 21:04 495 查看
/*
********************************************
学 生 经 验 值 管 理 系 统 (简易)
********************************************
编译环境: Dev-C++5.10
使用语言: C++
实现方式: 单链表
初步实现功能:
1、导入文件建学生经验值表
2、插入学生
3、删除学生
4、显示全部学生信息
5、为某学号学生加指定经验值
6、为某学号学生减指定经验值 
7、按姓名查找学生经验值
8、求经验值最高的学生信息
9、存盘并退出
此处文件Student.txt 为自行建立。
(也可自行添加构建文件的功能)
********************************************
*/
#include <iostream>
#include <fstream>
#include <string>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAXSIZE 100
using namespace std;
bool undoing = false;

// 学生表结点
typedef struct Student
{
string s_Number;            // 学号
string s_Name;              // 姓名
double s_ExpVal;            // 经验值
int s_Length;               // 表长
struct Student *next;
} Student, *StudentList;

/*************************************************************************/
// 栈结点
typedef struct
{
string num;            // 学号
string name;           // 姓名
double expVal;         // 经验值

double changeExpVal;   // 增加或减少的经验值
string blackNum;       // 位置意义上的:被删除学生的下一个学生的学号
string oper;           // 进行的操作 "i""d1""d2""+""-"代表 插入 表尾删除 表中删除 加经验 减经验
} SNode;
// 栈结构
typedef struct
{
SNode *Base;
SNode *Top;
int stackSize;
} Stack;
// 栈初始化
void InitStack(Stack &S)
{
S.Base = new SNode[MAXSIZE];
if(!S.Base) exit(OVERFLOW);
S.Top = S.Base;
S.stackSize = MAXSIZE;
}
// 入栈
void Push(Stack &S, SNode node)
{
if(S.Top-S.Base == MAXSIZE) return;
*S.Top++ = node;                   // 压入栈顶,栈顶指针加1
}
// 出栈
void Pop(Stack &S, SNode &node)
{
if(S.Top == S.Base) return;   // 栈空
node = *--S.Top;                   // 栈顶指针减1,将栈顶元素赋给e
}

/*************************************************************************/

/*-----------------------------------------------------------------------*/
// 1、导入文件建学生经验值表
int CreateList(StudentList &L,Stack &stack)
{
L = new Student;            // 初始化表
L->next = NULL;
L->s_Length = 0;

ifstream Input("Student.txt",ios::in);
if(!Input)
{
cout<<"Cannot open the Student.txt."<<endl;
return ERROR;
}

Student *T_Stu;             // 临时结构体变量用于建立结点
Student *F_List;            // 跟踪表结点
F_List = L;
while(!Input.eof())         // 文本数据的输出
{
T_Stu = new Student;
Input>>T_Stu->s_Number;
Input>>T_Stu->s_Name;
Input>>T_Stu->s_ExpVal;
T_Stu->next = NULL;

F_List->next = T_Stu;
F_List = T_Stu;
L->s_Length++;
}

Input.close();
if(!L) return ERROR;
InitStack(stack);
return OK;
}

// 2、插入学生(某学号前)
int InsertStudent(StudentList &L,string T_Number,bool Judge,Stack &stack)
{
Student *N_Stu;         // 新进学生
Student *F_T_Stu;       // 新进学生的后继结点
Student *B_T_Stu;       // 新进学生的前驱结点
F_T_Stu = L;
B_T_Stu = L;

if(Judge == 1)          // 若在表尾插入新进学生
{
while(F_T_Stu->next)                        // 搜位置
F_T_Stu = F_T_Stu->next;

N_Stu = new Student;                        // 新进学生的信息
cout<<"请输入新进学生的信息:"<<endl;
cout<<"学号:";
cin>>N_Stu->s_Number;
cout<<"姓名:";
cin>>N_Stu->s_Name;
cout<<"经验值:";
cin>>N_Stu->s_ExpVal;
N_Stu->next = NULL;

F_T_Stu->next = N_Stu;                      // 嵌入表尾
L->s_Length++;

if(undoing == false)
{
/*-----*/           // 压入撤销栈
SNode node;
node.num = N_Stu->s_Number;
node.name = N_Stu->s_Name;
node.expVal = N_Stu->s_ExpVal;
node.oper = "i";
node.changeExpVal = 0;
node.blackNum = "";
Push(stack,node);
/*-----*/
}

return OK;
}
// 若在表中插入新进学生
while(F_T_Stu && F_T_Stu->s_Number!=T_Number)   // 搜位置
{
B_T_Stu = F_T_Stu;
F_T_Stu = F_T_Stu->next;
}

if(!F_T_Stu)
{
cout<<"找不到学号为 "<<T_Number<<"的学生!"<<endl;
return ERROR;
}

N_Stu = new Student;                            // 新进学生的信息
cout<<"请输入新进学生的信息:"<<endl;
cout<<"学号:";
cin>>N_Stu->s_Number;
cout<<"姓名:";
cin>>N_Stu->s_Name;
cout<<"经验值:";
cin>>N_Stu->s_ExpVal;

B_T_Stu->next = N_Stu;                          // 嵌入表中
N_Stu->next = F_T_Stu;
L->s_Length++;

if(undoing == false)
{
/*-----*/           // 压入撤销栈
SNode node;
node.num = N_Stu->s_Number;
node.name = N_Stu->s_Name;
node.expVal = N_Stu->s_ExpVal;
node.oper = "i";
node.changeExpVal = 0;
node.blackNum = "";
Push(stack,node);
/*-----*/
}

return OK;
}

// 3、删除学生
int DeleteStudent(StudentList &L,string T_Number,Stack &stack)
{
if(!L)
{
cout<<"表为空!无法删除!"<<endl;
return ERROR;
}
Student *F_T_Stu;           // 指向将要删除的结点
Student *B_T_Stu;           // 指向将要 被删除的结点 的前驱结点
F_T_Stu = B_T_Stu = L;

while(F_T_Stu && F_T_Stu->s_Number!=T_Number)   // 搜位置
{
B_T_Stu = F_T_Stu;
F_T_Stu = F_T_Stu->next;
}

if(!F_T_Stu)
{
cout<<"找不到学号为 "<<T_Number<<"的学生!"<<endl;
return ERROR;
}

B_T_Stu->next = F_T_Stu->next;                  // 将结点从表中除去

if(undoing == false)
{
/*-----*/           // 压入撤销栈
SNode node;
if(F_T_Stu->next)   // 表中删除
{
node.num    = F_T_Stu->s_Number;
node.name   = F_T_Stu->s_Name;
node.expVal = F_T_Stu->s_ExpVal;
node.oper    = "d2";
node.changeExpVal = 0;
node.blackNum     = F_T_Stu->next->s_Number;
Push(stack,node);
}
else                // 表尾删除
{
node.num    = F_T_Stu->s_Number;
node.name   = F_T_Stu->s_Name;
node.expVal = F_T_Stu->s_ExpVal;
node.oper   = "d1";
node.changeExpVal = 0;
node.blackNum     = "";
Push(stack,node);
}
/*-----*/
}

delete F_T_Stu;                                 // 释放被删除的结点
L->s_Length--;
return OK;
}

// 4、显示全部学生信息
void DisplayList(StudentList L)
{
Student *F_List;
F_List = L->next;

cout<<"学生经验值表:"<<endl;
cout<<" _______________________________________________"<<endl;
cout<<"|    学号  |   姓名  |   经验值 |"<<endl;
cout<<"------------------------------------------------"<<endl;
for(int i=1; i<=L->s_Length; i++)
{
cout<<"|    "<<F_List->s_Number<<"  ";
cout<<"|    "<<F_List->s_Name<<"    ";
cout<<"|    "<<F_List->s_ExpVal<<"  |"<<endl;
cout<<"------------------------------------------------"<<endl;
F_List = F_List->next;
}

cout<<"打印完毕."<<endl<<endl;
}

// 5、为某学号学生加指定经验值
int IncreaseExpVal(StudentList &L,string T_Number,Stack &stack)
{
double Value;           // 将要增加的经验值
Student *T_Stu;         // 指向将要操作的学生
T_Stu = L;

while(T_Stu && T_Stu->s_Number!=T_Number)   // 搜位置
T_Stu = T_Stu->next;

if(!T_Stu)
{
cout<<"找不到学号为 "<<T_Number<<"的学生!"<<endl;
return ERROR;
}

cout<<"请问要给学生 "<<T_Stu->s_Name<<" 加多少经验值?:";
cin>>Value;             // 加经验值

T_Stu->s_ExpVal += Value;

if(undoing == false)
{
/*-----*/           // 压入撤销栈
SNode node;
node.num = T_Stu->s_Number;
node.name = T_Stu->s_Name;
node.expVal = T_Stu->s_ExpVal;
node.oper = "+";
node.changeExpVal = Value;
node.blackNum = "";
Push(stack,node);
/*-----*/
}

return OK;
}

// 6、为某学号学生减指定经验值 
int DecreaseExpVal(StudentList &L,string T_Number,Stack &stack)
{
double Value;           // 将要减少的经验值
Student *T_Stu;         // 指向将要操作的学生
T_Stu = L;

while(T_Stu && T_Stu->s_Number!=T_Number)   // 搜位置
T_Stu = T_Stu->next;

if(!T_Stu)
{
cout<<"找不到学号为 "<<T_Number<<"的学生!"<<endl;
return ERROR;
}

cout<<"请问要给学生 "<<T_Stu->s_Name<<" 减多少经验值?:";
cin>>Value;             // 减经验值

T_Stu->s_ExpVal -= Value;

if(undoing == false)
{
/*-----*/           // 压入撤销栈
SNode node;
node.num = T_Stu->s_Number;
node.name = T_Stu->s_Name;
node.expVal = T_Stu->s_ExpVal;
node.oper = "-";
node.changeExpVal = Value;
node.blackNum = "";
Push(stack,node);
/*-----*/
}

return OK;
}

// 7、按姓名查找学生经验值
int SearchExpVal(StudentList L,string T_Name)
{
Student *T_Stu;         // 将要操作的学生
T_Stu = L;

while(T_Stu && T_Stu->s_Name!=T_Name)   // 搜位置
T_Stu = T_Stu->next;

if(!T_Stu)
{
cout<<"找不到姓名为 "<<T_Name<<"的学生!"<<endl;
return ERROR;
}

cout<<"学生 "<<T_Stu->s_Name<<" 的经验值为:";  // 输出
cout<<T_Stu->s_ExpVal<<endl<<endl;

return OK;
}

// 8、求经验值最高的学生信息
void MaxExpVal(StudentList L)
{
Student *T_Stu;     // 追踪表中各结点
double   T_Max;     // 储存表中最大经验值

T_Stu = L->next;
T_Max = T_Stu->s_ExpVal;

for(int i=2; i<=L->s_Length; i++)   // 找最大经验值
{
T_Stu = T_Stu->next;
if(T_Stu->s_ExpVal > T_Max)
{
T_Max = T_Stu->s_ExpVal;
}
}

// 打印拥有最大经验值的学生信息
T_Stu = L;
cout<<"最高经验值学生:"<<endl;
cout<<" _______________________________________________"<<endl;
cout<<"|    学号  |   姓名  |   经验值 |"<<endl;
cout<<"------------------------------------------------"<<endl;
for(int i=1; i<=L->s_Length; i++)
{
T_Stu = T_Stu->next;
if(T_Stu->s_ExpVal==T_Max)
{
cout<<"|    "<<T_Stu->s_Number<<"   ";
cout<<"|    "<<T_Stu->s_Name<<" ";
cout<<"|    "<<T_Stu->s_ExpVal<<"   |"<<endl;
cout<<"------------------------------------------------"<<endl;
}
}
cout<<"打印完毕."<<endl<<endl;
}

// 9、撤销
// "i""d1""d2""+""-"代表 插入 表尾删除 表中删除 加经验 减经验
int Undo(StudentList &L,Stack &stack)
{
undoing == true;
SNode node;
Pop(stack,node);

if(node.oper == "i")
{
DeleteStudent(L,node.num,stack);
}
else if(node.oper == "d1")
{
Student *N_Stu;
Student *F_T_Stu;
F_T_Stu = L;

while(F_T_Stu->next)                        // 搜位置
F_T_Stu = F_T_Stu->next;

N_Stu = new Student;
N_Stu->s_Number = node.num;
N_Stu->s_Name = node.name;
N_Stu->s_ExpVal= node.expVal;
N_Stu->next = NULL;

F_T_Stu->next = N_Stu;        // 嵌入表尾
L->s_Length++;
}
else if(node.oper == "d2")
{
Student *N_Stu;
Student *F_T_Stu;
Student *B_T_Stu;
F_T_Stu = L;
B_T_Stu = L;

while(F_T_Stu && F_T_Stu->s_Number!=node.blackNum)   // 搜位置
{
B_T_Stu = F_T_Stu;
F_T_Stu = F_T_Stu->next;
}

N_Stu = new Student;
N_Stu->s_Number = node.num;
N_Stu->s_Name = node.name;
N_Stu->s_ExpVal = node.expVal;

B_T_Stu->next = N_Stu;
N_Stu->next = F_T_Stu;
L->s_Length++;
}
else if(node.oper == "+")
{
Student *T_Stu;         // 指向将要操作的学生
T_Stu = L;

while(T_Stu && T_Stu->s_Number!=node.num)   // 搜位置
T_Stu = T_Stu->next;
T_Stu->s_ExpVal -= node.changeExpVal;
}
else if(node.oper == "-")
{
Student *T_Stu;         // 指向将要操作的学生
T_Stu = L;

while(T_Stu && T_Stu->s_Number!=node.num)   // 搜位置
T_Stu = T_Stu->next;
T_Stu->s_ExpVal += node.changeExpVal;
}

undoing == false;
return OK;
}

// 10、存盘并退出
int SaveList(StudentList L)
{
ofstream Output("Student.txt",ios::out);
if(!Output)
{
cout<<"Cannot open the file Student.txt."<<endl;
return ERROR;
}

Student *T_Stu;         // 追踪表中各结点
T_Stu = L->next;

for(int i=1; i<=L->s_Length; i++)
{
Output<<endl<<T_Stu->s_Number<<endl;
Output<<T_Stu->s_Name<<endl;
Output<<T_Stu->s_ExpVal;
T_Stu = T_Stu->next;
}

Output.close();
return OK;
}
/*-----------------------------------------------------------------------*/

int main()
{
int     choose  = 0;
bool    Judge   = false;
string  Number  = " ";
string  Name    = " ";
StudentList List;
Stack   stack;

cout<<"      学 生 经 验 值 管 理 系 统 (简易)     "<<endl;
cout<<"*********************************************"<<endl;
cout<<"*         1、导入文件建学生经验值表         *"<<endl;
cout<<"*         2、插入学生                       *"<<endl;
cout<<"*         3、删除学生                       *"<<endl;
cout<<"*         4、显示全部学生信息               *"<<endl;
cout<<"*         5、为某学号学生加指定经验值       *"<<endl;
cout<<"*         6、为某学号学生减指定经验值      *"<<endl;
cout<<"*         7、按姓名查找学生经验值           *"<<endl;
cout<<"*         8、求经验值最高的学生信息         *"<<endl;
cout<<"*         9、撤销                           *"<<endl;
cout<<"*         10、存盘并退出                    *"<<endl;
cout<<"*********************************************"<<endl;

while(1)
{
cout<<"请输入您的选择:";
cin>>choose;

switch(choose)
{
case 1:
if(CreateList(List,stack))
cout<<"导入成功!建立学生经验值表!"<<endl<<endl;
else
{
cout<<"导入失败!文件异常!"<<endl<<endl;
return ERROR;
}
continue;
case 2:
cout<<"是否在表尾插入?(是则输入1,否则输入0):";
cin>>Judge;
if(Judge!=0 && Judge!=1)
{
cout<<"输入错误!请重新进行操作!"<<endl<<endl;
continue;
}
if(Judge==0)
{
cout<<"请问在哪位学生前插入?(请输入学号):";
cin>>Number;
}
else
{
Number = " ";
}
if(InsertStudent(List,Number,Judge,stack))
cout<<"插入成功!"<<endl<<endl;
else
cout<<"插入失败!请重新进行操作!"<<endl<<endl;
continue;
case 3:
cout<<"请问要删除哪位学生的信息?(请输入学号):";
cin>>Number;
if(DeleteStudent(List,Number,stack))
cout<<"删除成功!"<<endl<<endl;
else
cout<<"删除失败!请重新进行操作!"<<endl<<endl;
continue;
case 4:
DisplayList(List);
continue;
case 5:
cout<<"请问要给哪位学生加经验值?(请输入学号):";
cin>>Number;
if(IncreaseExpVal(List,Number,stack))
cout<<"增加成功!"<<endl<<endl;
else
cout<<"增加失败!请重新进行操作!"<<endl<<endl;
continue;
case 6:
cout<<"请问要给哪位学生减经验值?(请输入学号):";
cin>>Number;
if(DecreaseExpVal(List,Number,stack))
cout<<"减少成功!"<<endl<<endl;
else
cout<<"减少失败!请重新进行操作!"<<endl<<endl;
continue;
case 7:
cout<<"请问要查询哪位学生的经验值?(请输入姓名):";
cin>>Name;
if(!SearchExpVal(List,Name))
cout<<"查询失败!请重新进行操作!"<<endl<<endl;
continue;
case 8:
MaxExpVal(List);
continue;
case 9:
if(Undo(List,stack))
cout<<"撤销完毕!"<<endl<<endl;
continue;
case 10:
if(SaveList(List))
{
cout<<"数据已保存!"<<endl;
cout<<"正在退出程序..."<<endl;
cout<<"程序正常结束.感谢您的支持,欢迎下次使用!"<<endl;
break;
}
else
cout<<"数据保存失败!请重新进行操作!"<<endl<<endl;
continue;
default:
cout<<"输入异常!程序异常结束!!!"<<endl<<endl;
break;
}
break;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++