C++结合数据结构写的单链表方式的练习。
主文件stu.cpp
#include "CLinkList.cpp"
#include "CNode.cpp"
void Test();
void main()
{
cout<<"------------这是main函数------------"<<endl;
Test();
}
void Test()
{
cout<<"------------这是Test函数------------"<<endl;
LinkList* pList = new LinkList; //创建一个内存链表对象
cout<<"----------------CreateList----------------"<<endl;
//CreateList
pList->CreateList(); //初始化链表的成员函数
pList->ShowList();
cout<<"----------------GetListNode(3)----------------"<<endl;
//GetListNode
LinkNode* pNode = NULL;
pNode = pList->GetListNode(3);
if(pNode)
cout<<"Found the node."<<endl;
else
cout<<"Not Found the node."<<endl;
cout<<"----------------InsertList(0)----------------"<<endl;
//InsertList
pList->InsertList(0);
pList->ShowList();
cout<<"----------------DeleteList(0)----------------"<<endl;
//DeleteList
pList->DeleteList(0);
pList->ShowList();
cout<<"----------------GetHeadList----------------"<<endl;
//GetHeadList
pNode = NULL;
pNode = pList->GetHeadList();
if(pNode)
cout<<"Found head point."<<endl;
else
cout<<"Head point is NULL."<<endl;
cout<<"----------------GetListData----------------"<<endl;
//GetListData
pList->ShowListData(3);
cout<<"----------------DestroyList(3)----------------"<<endl;
//DestroyList(3)
pList->DestroyList(3);
pList->ShowList();
cout<<"----------------DestroyList(0)----------------"<<endl;
//DestroyList(0)
pList->DestroyList(0);
pList->ShowList();
delete pList; //释放内存
pList = NULL; //指针置空
}
结点部分头文件CNode.h
//class CNode
#ifndef _CNODE_H_
#define _CNODE_H_
#include <iostream>
using namespace std;
//出生年月结构
struct stData
{
int m_nYear;
int m_nMonth;
int m_nDay;
};
//各科成绩结构
struct stResult
{
double m_dSubject_1;
double m_dSubject_2;
double m_dSubject_3;
double m_dSubject_4;
double m_dSubject_5;
};
//声明学生信息的结构
struct stStudent
{
string m_strNumber; //学号
string m_strName; //姓名
char m_chSex; //性别
struct stData m_stData; //出生年月
string m_strAppearance; //政治面貌
struct stResult m_stResult; //各科成绩
};
//声明结点的类
typedef class CNode
{
private:
struct stStudent m_stStudent;
CNode* m_Next;
public:
CNode(); //构造函数
~CNode(); //析构函数
void SetNodeData(); //设置结点内容的成员函数
stStudent GetNodeData(); //获取结点内容的成员函数
void SetNodeNext(CNode* _Next); //设置结点Next指针的成员函数
void ShowNodeData(); //输出结点内容的成员函数
CNode* GetNodeNext(); //获取结点Next指针的成员函数
}LinkNode;
#endif
链表部分头文件CLinkList.h
//class CLinkList
#ifndef _CLINKLIST_H_
#define _CLINKLIST_H_
#include "CNode.h"
typedef class CLinkList
{
private:
LinkNode* m_Head; //链表的头指针
LinkNode m_Node; //链表的头结点
public:
CLinkList(); //构造函数
~CLinkList(); //析构函数
void CreateList(); //初始化链表的成员函数
LinkNode* GetListNode(int _nIndex); //按位置查找定位结点的成员函数
void InsertList(int _nIndex); //插入结点的成员函数
void DeleteList(int _nIndex); //删除某一结点的成员函数
LinkNode* GetHeadList(); //获取头指针的成员函数
void SetListData(int _nIndex); //设置链表中某一结点的值的成员函数
void ShowListData(int _nIndex); //显示链表中某一结点值的成员函数
void DestroyList(int _nIndex); //销毁某一位置后的链表的成员函数
void ShowList(); //显示链表的成员函数
}LinkList;
#endif
结点部分文件CNode.cpp
//class CNode
#include "CNode.h"
CNode::CNode() //构造函数
{
m_Next = NULL;
}
CNode::~CNode() //析构函数
{}
void CNode::SetNodeData()
{
char* pNumber = new char[30]; //用来接收字符串的临时变量
char* pName = new char[30];
char* pAppearance = new char[30];
cout<<"学号:";
cin>>pNumber;
m_stStudent.m_strNumber = pNumber;
cout<<"姓名:";
cin>>pName;
m_stStudent.m_strName = pName;
cout<<"性别:";
cin>>m_stStudent.m_chSex;
cout<<"出生年月"<<endl;
cout<<"年:";
cin>>m_stStudent.m_stData.m_nYear;
cout<<"月:";
cin>>m_stStudent.m_stData.m_nMonth;
cout<<"日:";
cin>>m_stStudent.m_stData.m_nDay;
cout<<"政治面貌:";
cin>>pAppearance;
m_stStudent.m_strAppearance = pAppearance;
cout<<"各科成绩"<<endl;
cout<<"Subject1:";
cin>>m_stStudent.m_stResult.m_dSubject_1;
cout<<"Subject2:";
cin>>m_stStudent.m_stResult.m_dSubject_2;
cout<<"Subject3:";
cin>>m_stStudent.m_stResult.m_dSubject_3;
cout<<"Subject4:";
cin>>m_stStudent.m_stResult.m_dSubject_4;
cout<<"Subject5:";
cin>>m_stStudent.m_stResult.m_dSubject_5;
delete[] pNumber; //释放内存
pNumber = NULL; //指针置空
delete[] pName;
pName = NULL;
delete[] pAppearance;
pAppearance = NULL;
}
stStudent CNode::GetNodeData() //返回结点内容即学生信息
{
return m_stStudent;
}
void CNode::SetNodeNext(CNode* _Next)
{
m_Next = _Next;
}
void CNode::ShowNodeData()
{
const char* pNumber = m_stStudent.m_strNumber.c_str();
const char* pName = m_stStudent.m_strName.c_str();
const char* pAppearance = m_stStudent.m_strAppearance.c_str();
cout<<"学号:"<<pNumber<<"\t"<<"姓名:"<<pName<<"\t"<<"性别:"<<m_stStudent.m_chSex<<endl;
cout<<"出生年月:"<<m_stStudent.m_stData.m_nYear<<"年"<<m_stStudent.m_stData.m_nMonth<<"月"<<m_stStudent.m_stData.m_nDay<<"日"<<"\t"<<"政治面貌:"<<pAppearance<<endl;
cout<<"各科成绩:"<<endl;
cout<<"Subject1:"<<m_stStudent.m_stResult.m_dSubject_1<<endl;
cout<<"Subject2:"<<m_stStudent.m_stResult.m_dSubject_2<<endl;
cout<<"Subject3:"<<m_stStudent.m_stResult.m_dSubject_3<<endl;
cout<<"Subject4:"<<m_stStudent.m_stResult.m_dSubject_4<<endl;
cout<<"Subject5:"<<m_stStudent.m_stResult.m_dSubject_5<<endl;
}
CNode* CNode::GetNodeNext()
{
return m_Next;
}
链表部分文件CLinkList.cpp
//class CLinkList
#include "CLinkList.h"
#include "CNode.h"
CLinkList::CLinkList()
{
cout<<"------------这是构造函数------------"<<endl;
m_Head = &m_Node; //链表的头指针指向头结点
m_Node.SetNodeNext(NULL); //将头结点的Next指针设置为NULL
}
CLinkList::~CLinkList()
{
cout<<"------------这是析构函数------------"<<endl;
}
void CLinkList::CreateList() //以向后追加的方式创建链表, 输入0结束
{
int nTemp = 0; //定义临时变量用于标志程序结束
cout<<"------------开始创建链表------------"<<endl;
CNode* pTemp = NULL; //定义一个临时结点指针, 用来增加新结点
CNode* pNode = m_Head; //定义一个标记指针, 并指向头结点
while(1)
{
pTemp = new LinkNode;
cout<<"输入下一结点信息"<<endl;
pTemp->SetNodeData(); //设置链表中结点的内容
cout<<"输0结束, 输1继续输入下一结点信息"<<endl;
cin>>nTemp;
pNode->SetNodeNext(pTemp); //让链尾的Next指针指向新的结点
if(nTemp == 0)
break;
pNode = pTemp; //将结尾元素向后移
}
cout<<"------------创建链表结束------------"<<endl;
}
LinkNode* CLinkList::GetListNode(int _nIndex)
{
cout<<"------------这是按位置查找定位结点的成员函数------------"<<endl;
LinkNode* pNode = m_Head->GetNodeNext(); //定义一个临时的结点指针, 初始化指向头结点
int Temp = 0; //定义一个临时变量, 用来标记已检查结点的个数
if(_nIndex == -1) //返回头结点即头指针
return m_Head;
if(_nIndex < -1) //-nIndex控制条件
{
cout<<"输入位置错误!"<<endl;
return 0;
}
while(pNode != NULL)
{
if(_nIndex == Temp)
return pNode;
pNode = pNode->GetNodeNext(); //临时结点向后移动
++Temp;
}
return pNode; //没找到结点时返回NULL
}
void CLinkList::ShowListData(int _nIndex);
void CLinkList::InsertList(int _nIndex)
{
cout<<"------------这是插入结点的成员函数------------"<<endl;
LinkNode* pNode = GetListNode(_nIndex - 1); //定义一个结点类的指针, 指向的是要插入位置的前一指针
LinkNode* pTemp = new CNode; //定义一个临时结点指针, 用来增加新结点
pTemp->SetNodeData(); //设置插入结点的内容
pTemp->SetNodeNext(pNode->GetNodeNext());
pNode->SetNodeNext(pTemp);
}
void CLinkList::DeleteList(int _nIndex)
{
cout<<"------------这是删除结点的成员函数------------"<<endl;
LinkNode* pNode = GetListNode(_nIndex - 1); //定义一个结点类的指针, 指向的是要删除位置的前一指针
LinkNode* pTemp = NULL; //定义一个临时结点指针, 用来指向要删除的结点
pTemp = pNode->GetNodeNext(); //把pTemp指针指向要删除的结点
pNode->SetNodeNext(pTemp->GetNodeNext()); //把pNode指针指向要删除的结点的后一个结点
delete pTemp; //删除结点
pTemp = NULL;
}
LinkNode* CLinkList::GetHeadList()
{
cout<<"------------这是获取头指针的成员函数------------"<<endl;
return m_Head;
}
void CLinkList::SetListData(int _nIndex)
{
cout<<"------------这是设置链表中某一结点的值的成员函数------------"<<endl;
CNode *pNode = GetListNode(_nIndex); //定义一个结点类的指针, 指向的是要修改内容位置的结点
pNode->SetNodeData(); //修改内容
}
void CLinkList::ShowListData(int _nIndex)
{
cout<<"------------这是显示链表某一结点的值的成员函数------------"<<endl;
CNode *pNode = GetListNode(_nIndex); //定义一个结点类的指针, 指向的是要获取内容位置的结点
pNode->ShowNodeData(); //显示该位置的结点内容
}
void CLinkList::DestroyList(int _nIndex)
{
cout<<"------------这是销毁某一位置后的链表的成员函数------------"<<endl;
LinkNode* pTemp = GetListNode(_nIndex - 1); //定义一个结点类的指针, 指向的是要销毁位置的前一结点
LinkNode* pNode = pTemp->GetNodeNext(); //定义一个结点类的指针, 指向的是要销毁位置的结点
while(pTemp->GetNodeNext() != NULL) //销毁动作的执行条件
{
pTemp->SetNodeNext(pNode->GetNodeNext()); //把需要销毁的位置的前结点的指针Next指向销毁位置的下一个结点
delete pNode; //删除结点
pNode = pTemp->GetNodeNext(); //把pNode指针重新指向需要销毁的位置的结点
}
}
void CLinkList::ShowList()
{
cout<<"------------这是显示链表的成员函数------------"<<endl;
int nTemp = 0; //定义一个临时的整型变量来控制输入的个数
LinkNode* pTemp = m_Head->GetNodeNext(); //定义一个结点类指针, 指向第0位的结点
if(pTemp == NULL)
cout<<"这是一个空链表!"<<endl;
while(pTemp != NULL)
{
pTemp->ShowNodeData();
++nTemp;
if(nTemp%5 == 0 && nTemp != 0) //控制每轮输出只能5个结点的内容
cout<<endl;
pTemp = pTemp->GetNodeNext();
}
}
只是个小练习,函数测试可用,具体功能待期末考试结束再做整理。