刚完成了复数计算器这个项目,怀着激动的心情开始第二个项目学籍管理系统,这个项目用到了双链表和模版的知识。用双链表的目的是为了能实现从首部插入和删除学生信息以及从尾部插入删除学生信息。用模版是为了更方便的修改数据。
程序分析
该项目最重要的是要用到双链表的知识,以及学生类中的运算符重载。双链表可以实现对数据进行插入删除等操作,是程序的核心。而学生类中运算符重载是为了使双链表能够对学生类进行操作,模版正是这个中间条件。
代码
mian.cpp
#include
#include "information.h"
#include "class.h"
#include
using namespace std;
int main()
{
DoubleLinkList <Information> List;
int Option;
Information Value;
do
{
cout<<"\n学籍管理系统"
<<"\n-------------------------"
<<"\n1.在首部插入一个学生信息。"
<<"\n2.在尾部插入一个学生信息。"
<<"\n3.从首部删除一个学生信息。"
<<"\n4.从尾部删除一个学生信息。"
<<"\n5.从首部输出学生信息。"
<<"\n6.从尾部输出学生信息。"
<<"\n7.按姓名查找学生。"
<<"\n8.按学号查找学生"
<<"\n9.将学生信息按学号从小到大排序。"
<<"\n10.将学生信息按分数从高到低排序。"
<<"\n11.将学生信息存入指定文件中。"
<<"\n12.读取指定文件中的学生信息。"
<<"\n0.退出。"
<<"\n------------------------"
<<"\n输入您的选择:";
cin>>Option;
switch(Option)
{
case 1:
{
cout<<"\n";
cin>>Value;
List.inserart_At_Front(Value);
system("pause");
system("cls");
break;
}
case 2:
{
cout<<"\n";
cin>>Value;
List.inserart_At_Rear(Value);
system("pause");
system("cls");
break;
}
case 3:
{
List.Remove_From_Front();
system("pause");
system("cls");
break;
}
case 4:
{
List.Remove_From_Rear();
system("pause");
system("cls");
break;
}
case 5:
{
List.Traverse_Forward();
system("pause");
system("cls");
break;
}
case 6:
{
List.Tracerse_Backward();
system("pause");
system("cls");
break;
}
case 12:
{
List.Read_File();
system("pause");
system("cls");
break;
}
case 11:
{
List.Write_file();
system("pause");
system("cls");
break;
}
case 9:
{
List.Sort_Data_By_Id();
system("pause");
system("cls");
break;
}
case 10:
{
List.Sort_Data_By_Score();
system("pause");
system("cls");
break;
}
case 7:
{
string p;
cout<<"请输入你要查询的学生姓名:";
cin>>p;
List.Search_According_Name(p);
system("pause");
system("cls");
break;
}
case 8:
{
string n;
cout<<"请输入你要查询的学生学号:";
cin>>n;
List.Search_According_Id(n);
system("pause");
system("cls");
break;
}
default:
{
Option=0;
break;
}
}
}
while(Option!=0);
return 0;
}
information.h
#include
#include
#include
using namespace std;
class Information
{
friend ostream& operator<<(ostream& output, Information& Target);//输出流重载
friend istream& operator>>(istream& input, Information& Target);//输入流重载
friend ofstream& operator<<(ofstream& output, Information& Target); //文件输入流
friend ifstream& operator>>(ifstream& input, Information& Target);//文件输出流
friend bool operator ==(Information, string);
public:
Information();
Information(Information&);
~Information();
operator float();
operator double();
string Name;
string Address;
string Id;
string Score;
string Sex;
};
Information::Information() :Name("\0"), Address("\0"), Id("\0"), Score("\0"), Sex("\0"){}
Information::Information(Information& Value)
{
Address = Value.Address;
Id = Value.Id;
Name = Value.Name;
Score = Value.Score;
Sex = Value.Sex;
}
Information::~Information(){}
Information::operator float()
{
float Temp = 0;
for (int i = 0; Score[i]; i++)
{
Temp *= 10;
Temp += (Score[i] - '0');
}
return Temp;
}
Information::operator double()
{
double Temp = 0;
for (int i = 0; Id[i]; i++)
{
Temp *= 10;
Temp += (Id[i] - '0');
}
return Temp;
}
bool operator ==(Information stu, string Name)//重载等号运算符,便于查找
{
if (stu.Name == Name || stu.Id == Name)
return true;
return false;
}
ostream& operator<<(ostream& output, Information& Target)
{
output << "姓名:" << Target.Name << endl;
output << "地址:" << Target.Address << endl;
output << "学号:" << Target.Id << endl;
output << "成绩:" << Target.Score << endl;
output << "性别:" << Target.Sex << endl;
return output;
}
istream& operator>>(istream& input, Information& Target)
{
cout << "姓名:"; input >> Target.Name;
cout << "地址:"; input >> Target.Address;
cout << "学号:"; input >> Target.Id;
cout << "成绩:"; input >> Target.Score;
cout << "性别:"; input >> Target.Sex;
return input;
}
ofstream& operator<<(ofstream& output, Information& Target)//重载文件输出流
{
output << Target.Name << endl;
output<< Target.Address << endl;
output<< Target.Id << endl;
output << Target.Score << endl;
output <<Target.Sex << endl;
return output;
}
ifstream& operator>>(ifstream& input, Information& Target)//重载文件输入流
{
input >> Target.Name;
input >> Target.Address;
input >> Target.Id;
input >> Target.Score;
input >> Target.Sex;
return input;
}
class.h
#include
#include
#include
#include
using namespace std;
template <class NodeType>class Node;
template <class NodeType>class DoubleLinkList;
template <class NodeType>
class Node
{
private:
friend class DoubleLinkList<NodeType>;//双链表是节点的友元
friend ostream& operator<<(ostream&,NodeType&);
friend istream& operator<<(istream&,NodeType&);
public:
Node();
Node(NodeType&);
~Node();
NodeType Data;//数据域
Node<NodeType>* NextNode;//右指针
Node<NodeType>* PreviousNode;//左指针
};
template<class NodeType>
ostream& operator<<(ostream& output,Node<NodeType>& Target)
{
output<<Target.Data;
return output;
}
template <class NodeType>
istream& operator<<(istream& input,Node<NodeType>& Target)
{
input>>Target.Data;
return input;
}
template <class NodeType>
Node<NodeType>::Node():Data(),NextNode(NULL),PreviousNode(NULL)//结点的无参构造函数
{
}
template <class NodeType>
Node<NodeType>::Node(NodeType &Value)//结点的有参构造函数
{
Data=Value;
NextNode=NULL;
PreviousNode=NULL;
}
template <class NodeType>
Node<NodeType>::~Node()//结点的析构函数
{
}
template <class NodeType>
class DoubleLinkList
{
public:
DoubleLinkList();
~DoubleLinkList();
bool isEmpty();
void inserart_At_Front(NodeType &Value);//头部插入
void inserart_At_Rear(NodeType &Value);//尾部插入
bool Remove_From_Front();
bool Remove_From_Rear();
void Traverse_Forward();//从头部遍历
void Tracerse_Backward();//从尾部遍历
int Lenth_of_DoubleLinkList();//得到双链表的长度
Node<NodeType> *CreateNode(NodeType &Value);//创建一个双链表
void Sort_Data_By_Id();//按学号排序
void Sort_Data_By_Score();//按分数排序
void Read_File();//读文件
void Write_file();//写文件
void Search_According_Name(string n);//按名字查询
void Search_According_Id(string p);//按学号查询
private:
Node<NodeType>* FirstNode;
Node<NodeType>* RearNode;
};
template <class NodeType>
DoubleLinkList<NodeType>::DoubleLinkList():FirstNode(NULL),RearNode(NULL)//双链表的无参构造函数
{
}
template <class NodeType>
DoubleLinkList<NodeType>::~DoubleLinkList()//双链表的析构函数
{
Node<NodeType> *CurrentNode=FirstNode,*TempNode;
while(CurrentNode!=NULL)
{
TempNode=CurrentNode;
CurrentNode=CurrentNode->NextNode;
delete TempNode;
}
}
template <class NodeType>
bool DoubleLinkList<NodeType>::isEmpty()//判断链表是否为空
{
if(FirstNode==NULL)
{
cout<<"这是第一位学生的信息"<<endl;
return true;
}
else
return false;
}
template <class NodeType>
Node <NodeType>*DoubleLinkList<NodeType>::CreateNode(NodeType &Value)//创建一个链表
{
Node<NodeType> *NewNode=new Node<NodeType>(Value);
assert(NewNode!=NULL);
return NewNode;
}
template <class NodeType>
void DoubleLinkList<NodeType>::inserart_At_Front(NodeType &Value)//头插法
{
Node<NodeType> *NewNode=CreateNode(Value);
if(isEmpty())
FirstNode=RearNode=NewNode;
else
{
FirstNode->PreviousNode=NewNode;
NewNode->NextNode=FirstNode;
FirstNode=NewNode;
FirstNode->PreviousNode=NULL;
}
//cout<Data;
cout<<"\n结点插入成功"<<endl;
}
template <class NodeType>
void DoubleLinkList<NodeType>::inserart_At_Rear(NodeType &Value)//尾插法
{
Node<NodeType> *NewNode=CreateNode(Value);
if(isEmpty())
FirstNode=RearNode=NewNode;
else
{
RearNode->NextNode=NewNode;
NewNode->PreviousNode=RearNode;
RearNode=NewNode;
RearNode->NextNode=NULL;
}
//cout<Data;
cout<<"\n结点插入成功"<<endl;
}
template <class NodeType>
bool DoubleLinkList<NodeType>::Remove_From_Front()//头部删除
{
if(isEmpty())
{
cout<<"\n没有学生信息,无法删除!"<<endl;
return false;
}
else
{
Node<NodeType> *CurrentNode=FirstNode;
if(FirstNode==RearNode)
FirstNode=RearNode=NULL;
else
{
FirstNode=FirstNode->NextNode;
FirstNode->PreviousNode=NULL;
}
delete CurrentNode;
cout<<"\n成功删除第一个学生的信息"<<endl;
return true;
}
}
template <class NodeType>
bool DoubleLinkList<NodeType>::Remove_From_Rear()//尾部删除
{
if(isEmpty())
{
cout<<"没有学生信息,无法删除!"<<endl;
return false;
}
else
{
Node<NodeType> *CurrentNode=RearNode;
if(FirstNode==RearNode)
FirstNode=RearNode=NULL;
else
{
RearNode=RearNode->PreviousNode;
RearNode->NextNode=NULL;
}
delete CurrentNode;
cout<<"\n成功删除最后一个学生的信息"<<endl;
return true;
}
}
template <class NodeType>
void DoubleLinkList<NodeType>::Traverse_Forward()//头部遍历
{
Node<NodeType> *CurrentNode=FirstNode;
while(CurrentNode!=NULL)
{
cout<<CurrentNode->Data<<" ";
CurrentNode=CurrentNode->NextNode;
}
}
template <class NodeType>
void DoubleLinkList<NodeType>::Tracerse_Backward()//尾部遍历
{
Node<NodeType> *CurrentNode=RearNode;
while(CurrentNode!=NULL)
{
cout<<CurrentNode->Data<<" ";
CurrentNode=CurrentNode->PreviousNode;
}
}
template <class NodeType>
void DoubleLinkList<NodeType>::Sort_Data_By_Id()//按学号排序
{
Node<NodeType> *CurrentNode,*NewNode;
NodeType TempNode;
for(NewNode=FirstNode;NewNode!=NULL;NewNode=NewNode->NextNode)
{
for(CurrentNode=NewNode->NextNode;CurrentNode!=NULL;CurrentNode=CurrentNode->NextNode)
{
if((double)NewNode->Data>(double)CurrentNode->Data)
{
TempNode=CurrentNode->Data;
CurrentNode->Data=NewNode->Data;
NewNode->Data=TempNode;
}
}
}
cout<<"\n按学号从小到大排序成功"<<endl;
}
template <class NodeType>
void DoubleLinkList<NodeType>::Sort_Data_By_Score()//按分数排序
{
Node<NodeType> *CurrentNode,*NewNode;
NodeType TempNode;
for(NewNode=FirstNode;NewNode!=NULL;NewNode=NewNode->NextNode)
{
for(CurrentNode=NewNode->NextNode;CurrentNode!=NULL;CurrentNode=CurrentNode->NextNode)
{
if((float)NewNode->Data<(float)CurrentNode->Data)
{
TempNode=CurrentNode->Data;
CurrentNode->Data=NewNode->Data;
NewNode->Data=TempNode;
}
}
}
cout<<"\n按分数从高到低排序成功"<<endl;
}
template <class NodeType>
void DoubleLinkList<NodeType>::Read_File()//从文件中读取信息
{
ifstream file("user.txt",ios::in);
NodeType TempData;
if(!file)
{
cout<<"没有原始文件!"<<endl;
system("pause");
exit(0);
}
Node<NodeType>*NewNode=new Node<NodeType>;
NewNode->PreviousNode=NULL;
NewNode->NextNode=NULL;
FirstNode=RearNode=NewNode;
file>>NewNode->Data;
while(!file.eof())//eof()到文件末尾会读两次
{
NewNode=new Node<NodeType>;
NewNode->PreviousNode=RearNode;
RearNode->NextNode=NewNode;
NewNode->NextNode=NULL;
RearNode=NewNode;
file>>NewNode->Data;
//cout<Data<
}
if(RearNode==FirstNode)
{
delete RearNode;
FirstNode=RearNode=NULL;
cout<<"文件为空"<<endl;
}
else
{
RearNode=RearNode->PreviousNode;
delete RearNode->NextNode;
RearNode->NextNode=NULL;
cout<<"读取成功"<<endl;
}
file.close();
}
template <class NodeType>
void DoubleLinkList<NodeType>::Write_file()//把信息写入文件中
{
ofstream out("user.txt");
if(!out)
{
cout<<"打开文件失败!"<<endl;
return;
}
Node<NodeType> *CurrentNode=FirstNode;
while(CurrentNode!=NULL)
{
out<<CurrentNode->Data;
CurrentNode=CurrentNode->NextNode;
}
cout<<"成功写入"<<endl;
out.close();
}
template <class NodeType>
void DoubleLinkList<NodeType>::Search_According_Id(string p)//按学号排序
{
Node<NodeType> *CurrentNode=FirstNode;
while(CurrentNode!=NULL)
{
if(CurrentNode->Data==p)
{
cout<<"该学生的信息为:"<<endl;
cout<<CurrentNode->Data<<endl;
return;
}
CurrentNode=CurrentNode->NextNode;
}
cout<<"没有该学生!"<<endl;
}
template <class NodeType>
void DoubleLinkList<NodeType>::Search_According_Name(string n)//按姓名查找
{
Node<NodeType> *CurrentNode=FirstNode;
while(CurrentNode!=NULL)
{
if(CurrentNode->Data==n)
{
cout<<"该学生的信息为:"<<endl;
cout<<CurrentNode->Data<<endl;
return;
}
CurrentNode=CurrentNode->NextNode;
}
cout<<"没有改学生!"<<endl;
}