用单链表编程实现一个简易的高校学籍管理系统
【实验题目内容】
用单链表编程实现一个简易高校学籍管理系统并完成报告。
(1)学生信息包括学号、姓名、性别、专业和出生年月等,采用单链表存储方式;
(2)提供建立、查询、删除、增加和更新等功能;
(3)设计主函数中测试各项功能。
【实验环境】(使用的软件):VS - 2010
【项目设计源代码】
//stdafx.h头文件即所需的头文件
#include <iostream>
#include <string>
using namespace std;
// linkNode.h单链表的结点类模板头文件
#pragma once //VS-2010自动生成的代码
// 单链表的结点
// T为单链表中元素的模板类型
template <class T>
class linkNode
{
public:
// 构造结点
linkNode(void);
// 析构结点
~linkNode(void);
// 元素
T data;
// 后继指针
linkNode<T>* next;
};
// 构造结点
template <class T>
linkNode<T>::linkNode(void)
{
}
// 析构结点
template <class T>
linkNode<T>::~linkNode(void)
{
}
// LinkList.h单链表类模板头文件
#pragma once
#include "linkNode.h"
// 单链表
// T为单链表中元素的模板类型
template <class T>
class LinkList
{
public:
// 默认构造函数
LinkList(void);
// 析构造函数
~LinkList(void);
protected:
// 单链表的头指针
linkNode<T>* head;
public:
// 遍历输出单链表
void Print(void);
// 根据数组Array中前Count个元素构造新的单链表
LinkList(T* Array, long Count);
// 求单链表的长度(元素个数,不包括头结点)
long Count(void);
// 如果第position个元素存在,则取出第position
// 个元素Data,返回true,否则,返回false
bool getData(long position, T& Data);
// 搜索元素Data,若找到,则返回其地址current
// 和前趋地址precursor,并返回true,否则,返回false
bool Search(T Data, linkNode<T>*& precursor, linkNode<T>*& current);
// 将原来的元素oldData更新为新元素newData,
// 更新成功,则返回true,否则,返回false
bool Update(T oldData, T newData);
// 在第position个位置插入新元素newData,
// 若插入成功,则返回true,否则,返回false
bool Insert(long position, T newData);
// 删除元素deleteData,删除成功,
// 则返回true,否则,返回false
bool Delete(T deleteData);
// 逆置单链表,逆置成功,则返回true,否则,返回false
bool Invert(void);
// 取头结点(地址)
linkNode<T>* getHead(void);
};
// 默认构造函数
template <class T>
LinkList<T>::LinkList(void)
{
// 动态分配头结点
head = new linkNode<T>;
if(head==NULL)
{
cerr<<"分配内存失败。"<<endl;
exit(1);
}
// (空链表)头结点的后继为空
head->next = NULL;
}
// 析构造函数
template <class T>
LinkList<T>::~LinkList(void)
{
linkNode<T>* deleteNode,*current=head;
while(current)
{
deleteNode=current;
current=current->next;
delete deleteNode;
}
head=NULL;
}
// 遍历输出单链表
template <class T>
void LinkList<T>::Print(void)
{
cout<<"head→[头结点]";
linkNode<T>* current=head->next;
while(current!=NULL)
{
cout<<"[-]→["<<current->data<<"]";
current=current->next;
}
cout<<"[^]"<<endl;
}
// 根据数组Array中前Count个元素构造新的单链表
template <class T>
LinkList<T>::LinkList(T* Array, long Count)
{
// 动态分配头结点
linkNode<T>* rear = head = new linkNode<T>;
if(rear==NULL)
{
cerr<<"分配内存失败。"<<endl;
exit(1);
}
linkNode<T>* current;
for(long Index=0;Index<Count;Index++)
{
current=new linkNode<T>;
if(current==NULL)
{
cerr<<"分配内存失败。"<<endl;
exit(1);
}
rear->next=current;
current->data=Array[Index];
rear=rear->next;
}
// 链尾的后继为空
rear->next = NULL;
}
// 求单链表的长度(元素个数,不包括头结点)
template <class T>
long LinkList<T>::Count(void)
{
linkNode<T>* current=head->next;
long count=0;
while(current!=NULL)
{
count++;
current=current->next;
}
return count;
}
// 如果第position个元素存在,则取出第position个元素Data,
// 返回true,否则,返回false
template <class T>
bool LinkList<T>::getData(long position, T& Data)
{
if(position<1)
{
return false;
}
else
{
linkNode<T>* current=head->next;
for(long count=1;current && (count<position);count++)
{
current=current->next;
}
if(current)
{
Data=current->data;
return true;
}
else
{
cerr<<"未找到第"<<position<<"个元素。"<<endl;
return false;
}
}
}
// 搜索元素Data,若找到,则返回其地址current
// 和前趋地址precursor,并返回true,否则,返回false
template <class T>
bool LinkList<T>::Search(T Data, linkNode<T>*& precursor, linkNode<T>*& current)
{
precursor = head;
current=head->next;
if(precursor==NULL || current==NULL)
{
return false;
}
while(current && current->data!=Data)
{
precursor = current;
current=current->next;
}
if(current && current->data==Data)
{
return true;
}
else
{
return false;
}
}
// 将原来的元素oldData更新为新元素newData,
// 更新成功,则返回true,否则,返回false
template <class T>
bool LinkList<T>::Update(T oldData, T newData)
{
linkNode<T>* precursor = head;
linkNode<T>* current=head->next;
if(Search(oldData,precursor,current))
{
// 找到了元素oldData,更新为新元素newData
current->data=newData;
return true;
}
else
{
return false;
}
}
// 在第position个位置插入新元素newData,若插入成功,
// 则返回true,否则,返回false
template <class T>
bool LinkList<T>::Insert(long position, T newData)
{
linkNode<T>* current=head;
long currentPosition=0;
while(current && currentPosition<position-1)
{
current=current->next;
currentPosition++;
}
if(current)
{
linkNode<T>* newNode=new linkNode<T>;
newNode->data=newData;
newNode->next=current->next;
current->next=newNode;
return true;
}
else
{
return false;
}
}
// 删除的元素deleteData,删除成功,
// 则返回true,否则,返回false
template <class T>
bool LinkList<T>::Delete(T deleteData)
{
linkNode<T>* precursor = head;
linkNode<T>* current=head->next;
if(Search(deleteData,precursor,current))
{
// 找到删除的元素deleteData,使其脱链
precursor->next=current->next;
// 释放被删除元素所占的空间
delete current;
// 删除成功,返回true
return true;
}
else
{
// 未删除的元素deleteData,返回false
return false;
}
}
// 逆置单链表,逆置成功,则返回true,否则,返回false
template <class T>
bool LinkList<T>::Invert(void)
{
if(head==NULL)
{
cerr<<"逆置的单链表不存在。"<<endl;
return false;
}
else
{
linkNode<T>* first,*current=head->next;
// 将逆置后的单链表初始化为空表
head->next=NULL;
// 遍历单链表中的结点
while(current)
{
first=current;
current=current->next;
// 将结点插入到逆置后单链表的表头
first->next=head->next;
head->next=first;
}
return true;
}
}
// 取头结点(地址)
template <class T>
linkNode<T>* LinkList<T>::getHead(void)
{
return head;
}
//Student.h
#pragma once
class Student
{
string ID;
string Name;
int Age;
string Speciality;
string Date;
public:
Student(void);
~Student(void);
void updateID(string id){ ID = id; }
void Print();
bool operator == (Student student);
bool operator != (Student student);
friend istream & operator >> (istream & in, Student & student);
friend ostream & operator << (ostream & out,Student & student);
};
//Student.cpp
#include "Stdafx.h"
#include "Student.h"
Student::Student(void)
{
}
Student::~Student(void)
{
}
bool Student::operator == (Student student)
{
return ID == student.ID;
}
bool Student::operator != (Student student)
{
return ID != student.ID;
}
istream & operator >> (istream & in, Student & student)
{
cout << "学号?";
in >> student.ID;
cout << "姓名?";
in >> student.Name;
cout << "年龄?";
in >> student.Age;
cout << "专业?";
in >> student.Speciality;
cout << "出生年月?";
in >> student.Date;
return in;
}
ostream & operator << (ostream & out, Student & student)
{
out << "学生的学号为" << student.ID << ",姓名为" << student.Name << ",年龄为" << student.Age << ",专业为" << student.Speciality << ",出生年月为" << student.Date;
return out;
}
//主函数
#include "stdafx.h"
#include "LinkList.h"
#include "Student.h"
int _tmain(int argc, _TCHAR* argv[])
{
//这个操作主要是设置运行窗口为白底黑字的
system("color F0");
//测试
cout << "//测试操作" << endl;
cout << "测试建立一个简易的学生管理系统studentList。";
LinkList<Student> studentList;
int position = 0;
cout << "测试遍历输出学生管理系统studentList:";
studentList.Print();
cout << "测试在学生管理系统studentList中增加1个学生。";
cout << endl;
Student student, oldStudent, newStudent, deleteStudent;
cout << "输入新学生的信息:";
cout << endl;
cin >> student;
if(studentList.Insert(position++, student))
{
cout << "已在学生管理系统studentList中增加1个新学生。" << student << "。新的学生管理系统studentList:";
}
else
{
cout << "在学生管理系统studentList中无法插入新学生。" << student <<"。原来的学生管理系统studentList:";
}
studentList.Print();
//查询
cout << endl;
cout << "//查询操作" << endl;
string id;
linkNode <Student> *p;
p = studentList.getHead();
cout << "测试在学生管理系统studentList中查询学生。" << endl;
cout << "找什么学号的学生?";
cin >> id;
student.updateID(id);
if(studentList.Search(student, p, p -> next))
{
cout << "找到学号为" << id << "的学生。" << student << "。" << endl;
}
else
{
cout << "未找到学号为" << id << "的学生。" << endl;
}
//更新
cout << endl;
cout << "//更新操作" << endl;
cout << "测试更新指定学号的学生。" << endl;
cout << "要更新什么学号的学生?";
cin >> id;
cout << "输入新学生的信息:" << endl;
cin >> newStudent;
oldStudent.updateID(id);
if(studentList.Update(oldStudent,newStudent))
{
cout << "学号为" << id << "的学生已更新为新学生。" << newStudent << "。新的学生管理系统studentList:";
}
else
{
cout << "未找学号为" << id << "的学生,未更新任何学生。原来的学生管理系统studentList:";
}
studentList.Print();
//删除
cout << endl;
cout << "//删除操作" << endl;
cout << "测试删除指定学号的学生。" << endl;
cout << "要删除什么学号的学生?";
cin >> id;
deleteStudent.updateID(id);
if(studentList.Delete(deleteStudent))
{
cout << "已删除学号为" << id << "的学生。" << "新的学生管理系统studentList:";
}
else
{
cout << "未找到学号为" << id << "的学生。未删除任何学生。原来的学生管理系统studentList:";
}
studentList.Print();
system("PAUSE");
return 0;
}
【项目测试运行结果截图】
备注:各位小可爱们如果有任何的疑问可以在评论区留下你的思考,大家一起进步 yo~*