您的位置:首页 > 数据库

简单的单链表排序 —— 学生管理程序

2010-09-19 01:13 429 查看
昨晚,正在准备考研的小C叫我帮他调试一下他的代码,看了他发的CPP,居然只有一个main函数,一大堆a1,b1,c1等变量,确实改得蛋疼,不如自己重写一个....

 

类说明:

1、Person

     抽象的类,可用该类派生出:学生、老师、清洁工等

 

2、Student

     学生类(派生自Person)

 

3、Node

     单链表的节点类

     包含:1、一个指向下一节点的指针

              2、一个指向学习类对象的指针

 

4、ListMgr

     链表管理器类的声明,包括链表排序、遍历、交换、添加、删除等方法

 

5、ListItr

     链表的迭代类声明(可省略)

 

6、AppClass

     应用程序实例类 —— 用来与用户进行交互操作

 

具体代码如下:

 

Person.h

//////////////////////////////////////////////////////////////////////////
// Person 抽象的类
// 可用该类派生出:学生、老师、清洁工等

#ifndef PERSON
#define PERSON	1

class Person
{
public:
Person();
virtual int	GetKey() = 0;
};

#endif

// end of file Person.h
//////////////////////////////////////////////////////////////////////////


 

Person.cpp

//////////////////////////////////////////////////////////////////////////
// Person抽象父类的具体实现

#include "Person.h"

Person::Person()
{
}

// end of file Person.h
//////////////////////////////////////////////////////////////////////////


 

Student.h

//////////////////////////////////////////////////////////////////////////
// Student.h	学生类

#ifndef STUDENT
#define STUDENT

#include "Person.h"

class Student : public Person
{
public:
Student();
Student(char [],int,int,int);
char*	GetName();
int		GetMath();
int		GetEnglish();
int		GetTotal();
int		GetKey();

private:
char	m_szName[20];		// 学生姓名
int		m_nMath;			// 数学成绩
int		m_nEnglish;			// 英语成绩
int		m_nTotal;			// 总分
int		m_nKey;				// 学生编号 (唯一编号,类似数据库的主键)
};
#endif

// end of file Student.h
//////////////////////////////////////////////////////////////////////////


 

Student.cpp

//////////////////////////////////////////////////////////////////////////
// Student 学生类的具体实现

#include "Student.h"
#include <string.h>

/************************************************************************/
/* 函数说明:默认构造函数
/* 函数参数:无
/* 返 回 值:无
/* 备注信息:无
/************************************************************************/
Student::Student()
{
}

/************************************************************************/
/* 函数说明:默认构造函数
/* 函数参数:szName			学生姓名
/*			 nMath			数学成绩
/*			 nEnglish		英语成绩
/*			 nKey			学生编号
/* 返 回 值:无
/* 备注信息:无
/************************************************************************/
Student::Student(char szName[],int nMath,int nEnglish,int nKey)
{
strncpy(m_szName,szName,strlen(m_szName));
m_nKey		= nKey;
m_nMath		= nMath;
m_nEnglish	= nEnglish;
m_nTotal	= nEnglish + nMath;
}

/************************************************************************/
/* 函数说明:获取学生姓名
/* 函数参数:无
/* 返 回 值:char*
/* 备注信息:无
/************************************************************************/
char* Student::GetName()
{
return m_szName;
}

/************************************************************************/
/* 函数说明:获取学生数学成绩
/* 函数参数:无
/* 返 回 值:int
/* 备注信息:无
/************************************************************************/
int Student::GetMath()
{
return m_nMath;
}

/************************************************************************/
/* 函数说明:获取学生英语成绩
/* 函数参数:无
/* 返 回 值:int
/* 备注信息:无
/************************************************************************/
int Student::GetEnglish()
{
return m_nEnglish;
}

/************************************************************************/
/* 函数说明:获取学生总成绩
/* 函数参数:无
/* 返 回 值:int
/* 备注信息:无
/************************************************************************/
int Student::GetTotal()
{
return m_nTotal;
}

/************************************************************************/
/* 函数说明:获取学生编号
/* 函数参数:无
/* 返 回 值:int
/* 备注信息:无
/************************************************************************/
int Student::GetKey()
{
return m_nKey;
}

// end of file Student.cpp
//////////////////////////////////////////////////////////////////////////


 

Node.h

//////////////////////////////////////////////////////////////////////////
// Node 单链表的节点类
// 包含:1、一个指向下一节点的指针
//		 2、一个指向学习类对象的指针
//

#ifndef NODE
#define NODE

#include "Student.h"

class Node
{
public:
Node(Student *);
Node*		GetNext();
Student*	GetStudent();
void		SetStudent(Student* ps);
void		SetNext(Node *);

private:
Student* m_pStudent;			// 该节点对应学生对象的指针
Node*	 m_pNext;				// 指向下一个节点
};
#endif

// end of file Node.h
//////////////////////////////////////////////////////////////////////////


 

Node.cpp

//////////////////////////////////////////////////////////////////////////
// Node 单链表的节点类 —— 具体实现方法
//
#include "Node.h"

/************************************************************************/
/* 函数说明:构造函数,以便初始化成员变量
/* 函数参数:theObj		学习类对象的指针
/* 返 回 值:无
/* 备注信息:无
/************************************************************************/
Node::Node(Student *theObj)
{
m_pStudent = theObj;
m_pNext    = 0;
}

/************************************************************************/
/* 函数说明:获取下一个节点的指针
/* 函数参数:无
/* 返 回 值:Node*		下一节点的指针
/* 备注信息:无
/************************************************************************/
Node* Node::GetNext()
{
return m_pNext;
}

/************************************************************************/
/* 函数说明:获取该学生对象的指针
/* 函数参数:无
/* 返 回 值:Student*		学生对象的指针
/* 备注信息:无
/************************************************************************/
Student* Node::GetStudent()
{
return m_pStudent;
}

/************************************************************************/
/* 函数说明:获取该学生对象的指针
/* 函数参数:无
/* 返 回 值:Student*		学生对象的指针
/* 备注信息:无
/************************************************************************/
void Node::SetStudent(Student* ps)
{
m_pStudent = ps;
}

/************************************************************************/
/* 函数说明:设置下一个节点的指针
/* 函数参数:nextNode		下一节点的指针
/* 返 回 值:无
/* 备注信息:无
/************************************************************************/
void Node::SetNext(Node *nextNode)
{
m_pNext = nextNode;
}

// end of file Node.cpp
//////////////////////////////////////////////////////////////////////////


 

ListMgr.h

//////////////////////////////////////////////////////////////////////////
// ListMgr 链表管理器类的声明
//

#ifndef LISTMGR
#define LISTMGR

#include "Node.h"
#include "Student.h"

class ListMgr
{
public:
ListMgr();
void		Insert(Student *);
Student*	Find(int);
int			Remove(int);
Node*		GetFirst();
void		Order(bool asc = true);
void		SwapNode(Node*,Node*);
bool		Compare(int Left, int Right, bool big=true);

private:
Node*		first;				// 头节点
};

#endif

// end of file ListMgr.h
//////////////////////////////////////////////////////////////////////////


 

ListMgr.cpp

//////////////////////////////////////////////////////////////////////////
// ListMgr 链表管理器类的具体实现
//

#include "ListMgr.h"
#include <iostream>
#include <assert.h>

using namespace std;

/************************************************************************/
/* 函数说明:构造函数
/* 函数参数:无
/* 返 回 值:无
/* 备注信息:初始化头结点
/************************************************************************/
ListMgr::ListMgr()
{
first = 0;
}

/************************************************************************/
/* 函数说明:在单链表中插入一个元素
/* 函数参数:theStudent	元素指针
/* 返 回 值:无
/* 备注信息:无
/************************************************************************/
void ListMgr::Insert(Student *theStudent)
{
Node *newNode,*current,*previous;
Student *currentStudent;

newNode = new Node(theStudent);
int		newKey = theStudent->GetKey();
if( !newNode )
{
cout<<"/n无法创建一个结点./n"<<endl;
return;
}

if (first == 0)
{
first = newNode;
}
else
{
int	firstNode = true;
current = first;
while(current != 0)
{
currentStudent = current->GetStudent();
if(newKey < currentStudent->GetKey())
break;
previous = current;
current  = current->GetNext();
firstNode = false;
}

// 如果是第一次插入,则将前一个节点指向这个新的节点
if(!firstNode)
previous->SetNext(newNode);
else
first = newNode;

// 将新的节点存放在当前链表中
newNode->SetNext(current);
}
}

/************************************************************************/
/* 函数说明:在单链表中查找一个元素
/* 函数参数:searchNum	节点的关键字,即学生编号
/* 返 回 值:成功返回该节点的指针,否则返回0
/* 备注信息:无
/************************************************************************/
Student* ListMgr::Find(int searchNum)
{
Student *currentStudent;
Node	*current;
current = first;

while(current != 0)
{
currentStudent = current->GetStudent();
if(searchNum == currentStudent->GetKey())
return currentStudent;
current = current->GetNext();
}
return 0;
}

/************************************************************************/
/* 函数说明:在单链表中删除一个元素
/* 函数参数:searchNum	节点的关键字
/* 返 回 值:成功返回true,否则返回false
/* 备注信息:无
/************************************************************************/
int	ListMgr::Remove(int searchNum)
{
Student *currentStudent;
Node	*current,*previous,*next;

if(first == 0)						// 如果当前链表为空则直接返回
return false;

int	firstNode = true;
current = first;

while(current != 0)
{
currentStudent = current->GetStudent();
if(searchNum == currentStudent->GetKey())
break;

previous = current;
current  = current->GetNext();
firstNode = false;				// 不是头节点
}

if(current == 0)					// 没有找到该节点则返回
return false;

if(!firstNode)
{
next = current->GetNext();		// 先获取该节点的后一个节点
previous->SetNext(next);
}
else
first = current->GetNext();		// 将后一个节点设置为当前节点

// 这里内存释放有点问题,未调试完毕
//	delete current->GetStudent();		// 删除学生对象的内存空间
//	delete current;						// 删除节点对象的内存空间
return true;						// 成功删除某节点
}

/************************************************************************/
/* 函数说明:在单链表中获取头节点元素
/* 函数参数:无
/* 返 回 值:Node*		头节点元素
/* 备注信息:无
/************************************************************************/
Node* ListMgr::GetFirst()
{
return first;
}

/************************************************************************/
/* 函数说明:比较大小函数
/* 函数参数:big==true 升序 ==false 降序可用来控制排序升序降序
/* 返 回 值:bool值 是否大于或小于
/* 备注信息:无
/************************************************************************/
bool ListMgr::Compare(int Left, int Right, bool big)
{
return big ? Left>Right : Left<Right;
}

/************************************************************************/
/* 函数说明:根据学生总分进行排序
/* 函数参数:asc	true升序// false降序
/* 返 回 值:无
/* 备注信息:找最值然后与前面的交换 重复这样的过程 完成排序
/************************************************************************/
void ListMgr::Order(bool asc /*= true*/)
{
for (Node *pNodei=first; pNodei!=NULL; pNodei=pNodei->GetNext())
{
Node* pNoteM = pNodei;
Node *pNodej = pNodei->GetNext();
for (; pNodej!=NULL; pNodej=pNodej->GetNext())
{
if(Compare(pNoteM->GetStudent()->GetTotal(),
pNodej->GetStudent()->GetTotal(), asc))
{
pNoteM = pNodej;//记录最值
}
}
SwapNode(pNodei, pNoteM);//交换本节点和最值
}
}

/************************************************************************/
/* 函数说明:交换两个结点的位置
/* 函数参数:无
/* 返 回 值:无
/* 备注信息:无
/************************************************************************/
void ListMgr::SwapNode(Node *pLeft,Node *pRight)
{
assert(pLeft!=NULL && pRight!=NULL);
Student* temp = pLeft->GetStudent();
pLeft->SetStudent(pRight->GetStudent());
pRight->SetStudent(temp);
}

// end of file ListMgr.cpp
//////////////////////////////////////////////////////////////////////////


 

ListItr.h

//////////////////////////////////////////////////////////////////////////
// ListItr 链表的迭代类声明
//

#ifndef LISTITR
#define LISTITR

#include "Node.h"
#include "ListMgr.h"

class ListItr
{
public:
ListItr(ListMgr *);
Student*	GetNext();

private:
Node*		m_pCurNode;		// 当前的节点
ListMgr*	m_pList;		// 当前链表管理器的指针
};

#endif

// end of file ListItr.h
//////////////////////////////////////////////////////////////////////////


 

ListItr.cpp

//////////////////////////////////////////////////////////////////////////
// ListMgr 链表的迭代类 —— 具体实现方法
//

#include "ListItr.h"

/************************************************************************/
/* 函数说明:构造函数
/* 函数参数:whichList	链表管理器的指针
/* 返 回 值:无
/* 备注信息:用来初始化链表管理器对象的指针
/************************************************************************/
ListItr::ListItr(ListMgr *whichList)
{
m_pCurNode = 0;
m_pList = whichList;
}

/************************************************************************/
/* 函数说明:在链表管理器实例中获取下一个节点的学生数据
/* 函数参数:无
/* 返 回 值:成功返回该数据,否则返回0
/* 备注信息:无
/************************************************************************/
Student* ListItr::GetNext()
{
if(m_pCurNode == 0)
m_pCurNode = m_pList->GetFirst();
else
m_pCurNode = m_pCurNode->GetNext();

if(m_pCurNode != 0)
return m_pCurNode->GetStudent();
else
return 0;
}

// end of file ListItr.cpp
//////////////////////////////////////////////////////////////////////////


 

AppClass.h

//////////////////////////////////////////////////////////////////////////
// AppClass.h		应用程序实例类 —— 用来与用户进行交互操作

#ifndef APPCLASS
#define APPCLASS

#include "ListMgr.h"

//////////////////////////////////////////////////////////////////////////
// 主界面程序交互 —— 当前操作类型
#define INSERT			1		// 添加学生
#define REMOVE			2		// 删除学生
#define VIEW			3		// 查看全部
#define ORDER			4		// 升序
#define ORDER_BY_DESC	5		// 降序
#define QUIT			6		// 退出程序

class AppClass
{
private:
ListMgr *m_pListMgr;		// 链表管理器指针
int		ShowMenu();			// 显示菜单
void	AddStudent();		// 添加学生
void	RemoveStudent();	// 删除学生
void	ViewAll();			// 默认
void	Order();			// 升序
void	OrderByDesc();		// 降序

public:
AppClass();
void	Run();
};

#endif

// end of file AppClass.h
//////////////////////////////////////////////////////////////////////////


 

AppClass.cpp

//////////////////////////////////////////////////////////////////////////
// AppClass 应用程序实例类 —— 具体实现方法
//

#include "AppClass.h"
#include "ListMgr.h"
#include "ListItr.h"
#include "Student.h"
#include <iostream>
using namespace std;

/************************************************************************/
/* 函数说明:构造函数
/* 函数参数:无
/* 返 回 值:无
/* 备注信息:无
/************************************************************************/
AppClass::AppClass()
{
m_pListMgr = new ListMgr();			// 第三处内存泄露
}

/************************************************************************/
/* 函数说明:启动应用程序实例
/* 函数参数:无
/* 返 回 值:无
/* 备注信息:无
/************************************************************************/
void AppClass::Run()
{
int		nChoice = ShowMenu();
while(nChoice != QUIT)
{
switch (nChoice)
{
case INSERT:
AddStudent();
break;
case REMOVE:
RemoveStudent();
break;
case VIEW:
ViewAll();
break;
case ORDER:
Order();
ViewAll();
break;
case ORDER_BY_DESC:
OrderByDesc();
ViewAll();
break;
case  QUIT:
break;
default:
cout<<"你的选择有误,请重试!"<<endl;
}
nChoice = ShowMenu();
}
}

/************************************************************************/
/* 函数说明:显示菜单项
/* 函数参数:无
/* 返 回 值:操作类型
/* 备注信息:无
/************************************************************************/
int	AppClass::ShowMenu()
{
cout<<"/n1、添加一个学生";
cout<<"/n2、删除一个学生";
cout<<"/n3、默认方式/t(按添加的先后顺序进行排列)";
cout<<"/n4、按升序查看";
cout<<"/n5、按降序查看";
cout<<"/n6、退出程序/n";
cout<<"/n请选择一项: ";

int		nChoice = 0;
cin>>nChoice;
return nChoice;
}

/************************************************************************/
/* 函数说明:新增一个学生
/* 函数参数:无
/* 返 回 值:无
/* 备注信息:无
/************************************************************************/
void AppClass::AddStudent()
{
Student *newStudent,*prevStudent;
int		nID;
char	szName[20] = "";
int		nMath	   = 0;
int		nEnglish   = 0;

cout<<"/n请依次输入:/n编号/t姓名/t数学/t英语"<<endl;
cout<<"(提示:以空格分割或TAB键即可.)/n";
cin>>nID>>szName>>nMath>>nEnglish;

prevStudent = m_pListMgr->Find(nID);					// 先判断编号是否存在
if(prevStudent != 0)
{
cout<<"/n添加失败! (错误原因:当前学生编号已经存在.)/n";
return;
}

newStudent  = new Student(szName,nMath,nEnglish,nID);	// 第二处内存泄露
m_pListMgr->Insert(newStudent);
}

/************************************************************************/
/* 函数说明:删除一个学生
/* 函数参数:无
/* 返 回 值:无
/* 备注信息:无
/************************************************************************/
void AppClass::RemoveStudent()
{
int		nID = 0;
int		nResult = 0;

cout<<"请输入学生编号:";
cin>>nID;
nResult = m_pListMgr->Remove(nID);
if(nResult)
cout<<"删除成功!"<<endl;
else
cout<<"删除失败!(请先检查该编号是否存在.)"<<endl;
}

/************************************************************************/
/* 函数说明:查看全部
/* 函数参数:无
/* 返 回 值:无
/* 备注信息:按默认添加的顺序进行排列
/************************************************************************/
void AppClass::ViewAll()
{
Student *current;
ListItr	*theIterator;

theIterator = new ListItr(m_pListMgr);		// 第一处内存泄漏
current = theIterator->GetNext();

bool	bEmpty = false;						// 检查是当前链表是否为空
if(current == 0)
bEmpty = true;

cout<<"/n编号/t姓名/t数学/t英语/t总分"<<endl;
while(current != 0)
{
cout<<current->GetKey()<<"/t";
cout<<current->GetName()<<"/t";
cout<<current->GetMath()<<"/t";
cout<<current->GetEnglish()<<"/t";
cout<<current->GetTotal()<<endl;

current = theIterator->GetNext();
}
if(bEmpty)
cout<<"当前记录为空!/n";
}

/************************************************************************/
/* 函数说明:排序并查看(升序)
/* 函数参数:无
/* 返 回 值:无
/* 备注信息:无
/************************************************************************/
void AppClass::Order()
{
m_pListMgr->Order();
}

/************************************************************************/
/* 函数说明:排序并查看(降序)
/* 函数参数:无
/* 返 回 值:无
/* 备注信息:无
/************************************************************************/
void AppClass::OrderByDesc()
{
m_pListMgr->Order(false);
}

// end of file AppClass.cpp
//////////////////////////////////////////////////////////////////////////


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息