模板实现学籍管理

//有一些小错误,但不影响整体的运行
1 .程序说明
本程序是一个双向链表的典型示范程序,双向链表的结点为模板类型,在示范程序中,模板的结点为整型。
2. 程序设计要求
(1)将模板类型改为学生类class information,成员数据有:姓名、家庭住址、学号、成绩、性别等,成员函数有:构造、析构、按姓名比较、按学号比较等,并重载输入 、输出运算符。
(2)完善双向链表类的成员函数,增加按结点内容(姓名、学号)排序的成员函数,增加通过查找结点内容(姓名、学号)删除指定结点的成员函数;增加可以通过结点部分内容(姓名、学号)查找并输出结点全部内容的成员函数。
(3)增加双向链表对文件的操作,可以从数据文件中读取数据输入至双向链表,并将新的操作结果保存在数据文件中。
3. 程序设计的源代码及注释
#include
#include
using namespace std;
template class Node; //结点结构
template class DoubleLinkList; //双向链表类
template //定义类模板
class Node
{friend class DoubleLinkList ;
private:
NodeType Data; //模板类型的结点
Node *NextNode; //前向指针
Node *PreviousNode; //后向指针
public:
Node(); //构造函数
Node(NodeType &Value);
~Node(); //析构函数
};
template //定义类模板
class DoubleLinkList
{private:
Node *FirstNode; //链表首部指针
Node *RearNode; //链表尾部指针
public:
DoubleLinkList(); //双向链表构造函数
~DoubleLinkList(); //双向链表析构函数
bool IsEmpty(); //判断是否为空链表
void InsertAtFront(NodeType &Value); //结点插入链表头
void InsertAtRear(NodeType &Value); //结点插入链表尾
void InsertAtMiddle(NodeType &Value);
bool RemoveFromFront(); //删除链表头的结点
bool RemoveFromRear();
void TraverseForward(); //从链表头部输出链表
void TraverseBackwards();
//int LengthOfDoubleLinkList(); //返回链表长度
// Node *CreateNode(NodeType &Value);//生成链表
};
int main()
{DoubleLinkList List;
int Option,Value=0 ;
do {cout<<"\n双向链表菜单"
<<"\n____________"
<<"\n1.)在链表首部插入一个结点。"
<<"\n2.)在链表尾部插入一个结点。"
<<"\n3.)从链表首部删除一个结点。"
<<"\n4.)从链表尾部删除一个结点。"
<<"\n5.)从链表首部输出结点内容。"
<<"\n6.)从链表尾部输出结点内容。"
<<"\n0.)退出。"
<<"\n 输入您的选择:\t";
cin>>Option;
switch(Option)
{case 1:
{cout<<"\n输入结点数据:";
cin>>Value;
List.InsertAtFront(Value);
break;
}
case 2:
{ cout<<"\n 输入结点数据:";
cin>>Value;
List.InsertAtRear(Value);
break;
}
case 3:
{ List.RemoveFromFront();
break;
}
case 4:
{ List.RemoveFromRear();
break;
}
case 5:
{ List.TraverseForward();
break;
}
case 6:
{ List.TraverseBackwards();
break;
}
default:
{ Option=0;
break;
}
}
}
while(Option!=0);
return 0;
}

template
Node::Node():Data(NULL),NextNode(NULL),PreviousNode(NULL){}
template
Node ::Node(NodeType &Value):Data(Value),NextNode(NULL),PreviousNode(NULL){}
template
Node ::~Node(){}
template
DoubleLinkList ::DoubleLinkList():FirstNode(NULL),RearNode(NULL){}
template
DoubleLinkList ::~DoubleLinkList()
{ Node *CurrentNode=FirstNode,*TempNode;
while (CurrentNode!=NULL)
{TempNode=CurrentNode;
CurrentNode=CurrentNode->NextNode;
delete TempNode;
}
}
template
bool DoubleLinkList ::IsEmpty()
{ if (FirstNodeNULL)
{cout<<"\n 没有建立双向链表。";
return true;
}
else
return false;
}
template
Node *DoubleLinkList ::CreateNode(NodeType &Value)
{ Node *NewNode=new Node(Value);
assert(NewNode!=NULL);
return NewNode;
}
template
void DoubleLinkList ::InsertAtFront(NodeType &Value)
{ Node *NewNode=CreateNode(Value);
if (IsEmpty())
{ FirstNode=RearNode=NewNode;}
else
{ FirstNode->PreviousNode=NewNode;
NewNode->NextNode=FirstNode;
FirstNode=NewNode;
FirstNode->PreviousNode=NULL;
}
cout<Data;
cout<<"\n 结点成功插入。";
}
template
void DoubleLinkList ::InsertAtRear(NodeType &Value)
{Node *NewNode=CreateNode(Value);
if (IsEmpty())
{ FirstNode=RearNode=NewNode;}
else
{ NewNode->PreviousNode=RearNode;
RearNode->NextNode=NewNode;
RearNode=NewNode;
RearNode->NextNode=NULL;
}
cout<Data;
cout<<"\n 结点成功插入。";
}
template
bool DoubleLinkList ::RemoveFromFront()
{if (IsEmpty())
{cout<<"\n 没有链表,不能进行删除操作。";
return false;
}
else
{
Node *CurrentNode=FirstNode;
if (FirstNode
RearNode)
FirstNode=RearNode=NULL;
else
{ FirstNode=FirstNode->NextNode;
FirstNode->PreviousNode=NULL;
}
delete CurrentNode;
cout<<"\n 结点成功删除。\n";
return true;
}
}
template
bool DoubleLinkList ::RemoveFromRear()
{ if (IsEmpty())
{cout<<"\n 没有链表,不能进行删除操作。";
return false;
}
else
{ Node *TempNode=RearNode;
if (FirstNode==RearNode)
FirstNode=RearNode=NULL;
else
RearNode=RearNode->PreviousNode;
RearNode->NextNode=NULL;
delete TempNode;
cout<<"\n 结点成功删除。";
return true;
}
}
template
void DoubleLinkList ::TraverseForward()
{ Node *CurrentNode=FirstNode;
cout<<"\n 从首部输出链表。\n";
while (CurrentNode!=NULL)
{ cout<Data<<" “;
CurrentNode=CurrentNode->NextNode;
}
}
template
void DoubleLinkList ::TraverseBackwards()
{ Node *CurrentNode=RearNode;
cout<<”\n 从尾部输出链表。 \n";
while (CurrentNode!=NULL)
{ cout<Data<<" ";
CurrentNode=CurrentNode->PreviousNode;
}
}
主函数main.cpp

#include<iostream>
#include<string>
#include"Stu_Class.h"
#include"Inforamtion.h" 
int main()
{
	char c;
	DoubleLinkList <Information> List;
	int Option,Value=0    ;
	do 
	{
		system("cls");
		cout<<"\n双向链表菜单";
		cout<<"\n1.)在链表首部插入一个学生信息结点。";
		cout<<"\n2.)在链表尾部插入一个学生信息结点。";
		cout<<"\n3.)从链表首部删除一个学生信息结点。";
		cout<<"\n4.)从链表尾部删除一个学生信息结点。";
		cout<<"\n5.)从链表首部输出学生信息结点内容。";
		cout<<"\n6.)从链表尾部输出学生信息结点内容。";
		cout<<"\n7.)读取指定文件的学生信息到链表中。";
		cout<<"\n8.)将当前链表的信息存入指定文件中。";
		cout<<"\n9.)将当前链表的学生信息按学号排序。";
		cout<<"\n10.)将当前链表的学生信息按分数排序。";
		cout<<"\n11.)按姓名查找学生。";
		cout<<"\n12.)按学号查找学生。" ;
		cout<<"\n0.)退出。";
		cout<<"\n输入您的选择:\t";
		cin>>Option;
		switch(Option)
		{
			case 1:
				{
					List.Insert_At_Front();
					break;
				}
			case 2:
				{
					List.Insert_At_Rear();
					break;
				}
			case 3:
				{
					List.Remove_From_Front();
					break;
				}
			case 4:
				{
					List.Remove_From_Rear();
					break;
			    }
			case 5:
				{
					List.Traverse_Forward();
					break;
				}
			case 6:
				{
					List.Traverse_Backward();
					break;
			    }
		    case 7:
			    {
			    	List.Read_File("E:\学生信息.txt");
			    	break;
				}
			case 8:
				{
					List.Write_File("E:\学生信息.txt");
					break;
				}
			case 9:
				{
					List.Sort_Data_By_Id();
					break;
				}
			case 10:
				{
					List.Sort_Data_By_Score();
					break;
				}
			case 11:
				{
					List.Search_According_Name();
					break;
				}
			case 12:
				{
					List.Search_According_Id();
					break;
				}
			default:
			{
				Option=0;
				break;
			}
		}
	}while(Option!=0);
	return 0;
}

Inforamtion.h

#include<iostream>
#include<fstream>
#include<string>
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<<"\r"<<"\n";
		output << Target.Address<<"\r"<<"\n";
		output << Target.Id<<"\r"<<"\n";
		output << Target.Score<<"\r"<<"\n";
		output << Target.Sex<<"\r"<<"\n";
		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;
	}

Stu_Class.h

#include <iostream>
#include <cassert>
#include <string>
#include <fstream> 
using namespace std;      
template <typename NodeType> class Node;            //结点结构
template <typename NodeType> class DoubleLinkList;  //双向链表类
template <typename NodeType>                        //定义类模板
class Node
{
	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<typename NodeType>
istream& operator>>(istream& input, Node<NodeType>& Target)
{
	input >> Target.Data;
	return input;
}

template<typename NodeType>
istream& operator>>(ostream& output, Node<NodeType>& Target)
{
	output >> Target.Data;
	return output;
}

template <typename NodeType>                      //定义类模板
class DoubleLinkList
{
private:
     Node <NodeType> *FirstNode;               //链表首部指针
	 Node <NodeType> *RearNode;                //链表尾部指针
public:
	 DoubleLinkList();                         //双向链表构造函数
	 ~DoubleLinkList();                        //双向链表析构函数
	 bool IsEmpty();                           //判断是否为空链表
	 void Insert_At_Front();      //结点插入链表头
	 void Insert_At_Rear();       //结点插入链表尾
	 bool Remove_From_Front();                   //删除链表头的结点
	 bool Remove_From_Rear();
	 void Traverse_Forward();                   //从链表头部输出链表
	 void Traverse_Backward();
	 int Length_Of_DoubleLinkList();             //返回链表长度
	 Node <NodeType>* CreateNode();//生成链表
	 void Sort_Data_By_Id();
	 void Sort_Data_By_Score();
	 void Read_File(char*);
	 void Write_File(char* FileName);
	 void Search_According_Name();
	 void Search_According_Id();
};

template <typename NodeType>
Node<NodeType>::Node():Data(),NextNode(NULL),PreviousNode(NULL){}

template <typename NodeType>
Node <NodeType>::Node(NodeType &Value):Data(Value),NextNode(NULL),PreviousNode(NULL){}

template <typename NodeType>
Node <NodeType>::~Node(){}

template <typename NodeType>
DoubleLinkList <NodeType>::DoubleLinkList():FirstNode(NULL),RearNode(NULL){} 

template <typename NodeType>
DoubleLinkList <NodeType>::~DoubleLinkList()
{ 
	Node<NodeType> *CurrentNode=FirstNode,*TempNode;
	while (CurrentNode!=NULL)
	{
		TempNode=CurrentNode;
		CurrentNode=CurrentNode->NextNode;
		delete TempNode;
	}
}

template <typename NodeType>
bool DoubleLinkList <NodeType>::IsEmpty()
{
	if (FirstNode==NULL)
	{
		cout<<"\n 没有建立双向链表。";
		return true;
	}
	else
		return false;
}

template <typename NodeType>
Node<NodeType>*DoubleLinkList <NodeType>::CreateNode()
{
	Node<NodeType> *NewNode=new Node<NodeType>;
	assert(NewNode!=NULL);
	cin>>*NewNode;
	return NewNode;
}

template <typename NodeType>
void DoubleLinkList <NodeType>::Insert_At_Front()
{
	Node <NodeType> *NewNode=CreateNode();
	if (IsEmpty())
	{
		NewNode->PreviousNode = NULL;
		NewNode->NextNode = NULL;
		FirstNode=RearNode=NewNode;
	}
	else
	{
		FirstNode->PreviousNode=NewNode;
		NewNode->NextNode=FirstNode;
		FirstNode=NewNode;
		FirstNode->PreviousNode=NULL;
	}
	cout<<"\n 结点成功插入。";
}

template <typename NodeType>
void DoubleLinkList <NodeType>::Insert_At_Rear()
{
	Node <NodeType> *NewNode=CreateNode();
	if (IsEmpty())
	{
		NewNode->PreviousNode = NULL;
		NewNode->NextNode = NULL;
		FirstNode=RearNode=NewNode;
	}
	else
	{
		NewNode->PreviousNode=RearNode;
		RearNode->NextNode=NewNode;
		RearNode=NewNode;
		RearNode->NextNode=NULL;
	}
	cout<<"\n 结点成功插入。";
}

template <typename NodeType>
bool DoubleLinkList <NodeType>::Remove_From_Front()
{
	if (IsEmpty())
	{
		cout<<"\n 没有链表,不能进行删除操作。";
		return false;
	}
	else
	{
		Node <NodeType> *CurrentNode=FirstNode;
		if (FirstNode==RearNode)
			FirstNode=RearNode=NULL;
		else
		{
			FirstNode=FirstNode->NextNode;
			FirstNode->PreviousNode=NULL;
		}
		delete CurrentNode;
		cout<<"\n 结点成功删除。\n";
		return true;
	}
}

template <typename NodeType>
bool DoubleLinkList <NodeType>::Remove_From_Rear()
{
	if (IsEmpty())
	{
		cout<<"\n 没有链表,不能进行删除操作。";
		return false;
	}
	else
	{
		Node <NodeType> *TempNode=RearNode;
		if (FirstNode==RearNode)
			FirstNode=RearNode=NULL;
		else 
			RearNode=RearNode->PreviousNode;
			RearNode->NextNode=NULL;
		delete TempNode;
		cout<<"\n 结点成功删除。";
		return true;
	}
}

template <typename NodeType>
void DoubleLinkList <NodeType>::Traverse_Forward()
{
	if(IsEmpty())
		cout << "链表是空的";
	else
	{
		Node<NodeType>* CurrentNode=FirstNode;
		while (CurrentNode)
		{
			cout << CurrentNode->Data << endl;
			CurrentNode = CurrentNode->NextNode;
		}
	}
	
}

template <typename NodeType>
void DoubleLinkList <NodeType>::Traverse_Backward()
{
	if(IsEmpty())
		cout<<"链表是空的";
	else
	{
		Node<NodeType>* CurrentNode = RearNode;
		while (CurrentNode)
		{
			cout << CurrentNode->Data << endl;
	    	CurrentNode = CurrentNode->PreviousNode;
		}
	}
}

template<typename NodeType>
void DoubleLinkList<NodeType>::Sort_Data_By_Score()
{
	if(IsEmpty())
	{
		cout << "链表是空的\n";
		return;
	}
	float MaxNumber = 0, Temp = 0;
	Node<NodeType> *CurrentNode, *NewFirstNode = NULL, *PreNode = NULL, *NewRearNode = FirstNode;
	do
	{
		CurrentNode = FirstNode;
		while (CurrentNode)
		{
			Temp = CurrentNode->Data;
			if (Temp > MaxNumber)
			{
				MaxNumber = Temp;
				NewFirstNode = CurrentNode;
			}
			Temp = 0;
			CurrentNode = CurrentNode->NextNode;
		}
		MaxNumber = 0;
		if ((NewFirstNode->PreviousNode) && (NewFirstNode->NextNode))
		{
			NewFirstNode->PreviousNode->NextNode = NewFirstNode->NextNode;
			NewFirstNode->NextNode->PreviousNode = NewFirstNode->PreviousNode;
			NewFirstNode->PreviousNode = NULL;
			NewFirstNode->NextNode = NULL;
		}
		else if (NewFirstNode->PreviousNode)
		{
			RearNode = RearNode->PreviousNode;
			NewFirstNode->PreviousNode->NextNode = NULL;
			NewFirstNode->PreviousNode = NULL;
		}
		else if (NewFirstNode->NextNode)
		{
			FirstNode = FirstNode->NextNode;
			NewFirstNode->NextNode->PreviousNode = NULL;
			NewFirstNode->NextNode = NULL;
		}
		else
		{
			FirstNode = NULL;
			RearNode = NULL;
		}
		if (!PreNode)
		{
			PreNode = NewFirstNode;
			NewRearNode = PreNode;
			continue;
		}
		NewFirstNode->NextNode = PreNode;
		PreNode->PreviousNode = NewFirstNode;
		NewFirstNode = PreNode;
	} while (!IsEmpty()) ;
	FirstNode = NewFirstNode;
	RearNode = NewRearNode;
	cout << "完成排序\n";
}

template<typename NodeType>
void DoubleLinkList<NodeType>::Sort_Data_By_Id()
{
	if(IsEmpty())
	{
		cout << "链表是空的\n";
		return;
	}
	float MaxNumber = 0, Temp = 0;
	Node<NodeType> *CurrentNode, *NewFirstNode = NULL, *PreNode = NULL, *NewRearNode = NewFirstNode;
	do
	{
		CurrentNode = FirstNode;
		while (CurrentNode)
		{
			Temp = CurrentNode->Data;
			if (Temp > MaxNumber)
			{
				MaxNumber = Temp;
				NewFirstNode = CurrentNode;
			}
			Temp = 0;
			CurrentNode = CurrentNode->NextNode;
		}
		MaxNumber = 0;
		if ((NewFirstNode->PreviousNode) && (NewFirstNode->NextNode))
		{
			NewFirstNode->PreviousNode->NextNode = NewFirstNode->NextNode;
			NewFirstNode->NextNode->PreviousNode = NewFirstNode->PreviousNode;
			NewFirstNode->PreviousNode = NULL;
			NewFirstNode->NextNode = NULL;
		}
		else if (NewFirstNode->PreviousNode)
		{
			RearNode = RearNode->PreviousNode;
			NewFirstNode->PreviousNode->NextNode = NULL;
			NewFirstNode->PreviousNode = NULL;
		}
		else if(NewFirstNode->NextNode )
		{
			FirstNode = FirstNode->NextNode;
			NewFirstNode->NextNode->PreviousNode = NULL;
			NewFirstNode->NextNode = NULL;
		}
		else
		{
			FirstNode = NULL;
			RearNode = NULL;
		}
		if (!PreNode)
		{
			PreNode = NewFirstNode;
			NewRearNode = PreNode;
			continue;
		}
		NewFirstNode->NextNode = PreNode;
		PreNode->PreviousNode = NewFirstNode;
		NewFirstNode = PreNode;
	} while (!IsEmpty()) ;
	FirstNode = NewFirstNode;
	RearNode = NewRearNode;
	cout << "完成排序\n";
}

template<typename NodeType>
void DoubleLinkList<NodeType>::Read_File(char* FileName)
{
	ifstream File;
	NodeType TempData;
	File.open(FileName, ios::in|ios::binary);
	if (!File)
	{
		cout << "文件未找到";
		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())
	{
		NewNode = new Node<NodeType>;
		NewNode->PreviousNode = RearNode;
		RearNode->NextNode = NewNode;
		NewNode->NextNode = NULL;
		RearNode = NewNode;
		File >> NewNode->Data;
	}
	if (RearNode == FirstNode)
	{
		delete RearNode;
		FirstNode = RearNode = NULL;
		cout << "文件为空";
	}
	else
	{
		RearNode = RearNode->PreviousNode;
		delete RearNode->NextNode;
		RearNode->NextNode = NULL;
		cout << "读取成功";
	}
	File.close();
}

template<typename NodeType>
void DoubleLinkList<NodeType>::Write_File(char* FileName)
{
	ofstream File(FileName, ios::out|ios::trunc|ios::binary);
	Node<NodeType>* CurrentNode = FirstNode;
	if (IsEmpty())
	{
		cout << "空链表\n";
		return;
	}
	while (CurrentNode)
	{
		File << CurrentNode->Data;
		CurrentNode = CurrentNode->NextNode;
	}
	cout << "链表储存成功";
}

template<typename NodeType>
void DoubleLinkList<NodeType>::Search_According_Name()
{
	if (IsEmpty())
		cout << "空链表";
	else
	{
		Node<NodeType>* CurrentNode = FirstNode;
		string Name;
		cout << "输入要查找的学生姓名:\t";
		cin >> Name;
		while (CurrentNode)
		{
			if (CurrentNode->Data == Name)
			{
				cout << CurrentNode->Data;
				return;
			}
			CurrentNode = CurrentNode->NextNode;
		}
		cout << "查无此人\n";
	}
}

template<typename NodeType>
void DoubleLinkList<NodeType>::Search_According_Id()
{
	if (IsEmpty())
		cout << "空链表";
	else
	{
		Node<NodeType>* CurrentNode = FirstNode;
		string Id;
		cout << "输入要查找的学生学号:\t";
		cin >> Id;
		while (CurrentNode)
		{
			if (CurrentNode->Data == Id)
			{
				cout << CurrentNode->Data;
				return;
			}
			CurrentNode = CurrentNode->NextNode;
		}
		cout << "查无此人\n";
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值