//有一些小错误,但不影响整体的运行
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 (FirstNodeRearNode)
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";
}
}