学习线性表后,整理,记录一下方便复习。
单链表:
#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;
#define LIST_SUCCESS 0
#define LIST_WRONG_LOC 1
#define LIST_EMPTY 2
template<class DATA>
class CLinkList
{
public:
CLinkList() :m_pHead(nullptr), m_nLenth(0){}
~CLinkList(){}
public:
//单链表
typedef struct _NODE
{
DATA Data;
_NODE* pNext;
}NODE, *pNODE;
public:
bool ListInsert( //在链表的某一个位置插入一个节点
int nLoc, //插入位置
DATA nData, //插入数据
int& nError //错误码
);
bool ListDelete( //在链表的某一个位置删除一个节点
int nLoc, //删除位置
DATA& nData, //删除数据
int& nError //错误码
);
bool ClearList( //清空链表
int& nError
);
void PrintList()
{
pNODE pTemp = m_pHead;
while (pTemp)
{
cout << pTemp->Data << " ";
pTemp = pTemp->pNext;
}
cout << endl;
pTemp = nullptr;
}
private:
pNODE m_pHead; //头结点指针
int m_nLenth; //链表长度
};
//************************************************************
// 函数名称: ListInsert
// 函数说明: 在链表的某一个位置插入一个节点
// 作 者: Dylan
// 时 间: 2015/08/25
// 参 数: int nLoc
// 参 数: int nData
// 参 数: int & nError
// 返 回 值: bool
//************************************************************
template<class DATA>
bool CLinkList<DATA>::ListInsert(int nLoc, DATA nData, int& nError)
{
//1.判断插入位置是否正确
if (nLoc>m_nLenth)
{
nError = LIST_WRONG_LOC;
return false;
}
//2.判断头结点是否为空,为空的话,直接在头结点插入数据
if (m_pHead == nullptr)
{
m_pHead = new NODE;
m_pHead->pNext = nullptr;
m_pHead->Data = nData;
nError = LIST_SUCCESS;
m_nLenth++;
return true;
}
//3.找到插入位置
//3.1找到插入位置的前一个节点
pNODE Pre = m_pHead;
pNODE pTemp = new NODE;
pTemp->Data = nData;
pTemp->pNext = nullptr;
for (int i = 0; i < nLoc - 1; i++)
{
Pre = Pre->pNext;
}
//3.2判断是否向头结点之前插入,处理特殊情况
if (nLoc == 0)
{
pTemp->pNext = m_pHead;
m_pHead = pTemp;
nError = LIST_SUCCESS;
m_nLenth++;
return true;
}
//4.执行插入操作
pTemp->pNext = Pre->pNext;
Pre->pNext = pTemp;
//5.插入成功,返回
nError = LIST_SUCCESS;
m_nLenth++;
return true;
}
//************************************************************
// 函数名称: ListDelete
// 函数说明: 在链表的某一个位置删除一个节点,并返回被删掉的数据
// 作 者: Dylan
// 时 间: 2015/08/25
// 参 数: int nLoc
// 参 数: int & nData
// 参 数: int & nError
// 返 回 值: bool
//************************************************************
template<class DATA>
bool CLinkList<DATA>::ListDelete(int nLoc, DATA& nData, int& nError)
{
//1.判断链表是否为空
if (m_pHead == nullptr)
{
nError = LIST_EMPTY;
return false;
}
//2.判断删除位置是否错误
if (nLoc >= m_nLenth)
{
nError = LIST_WRONG_LOC;
return false;
}
//3.找到要删除的位置
//3.1特殊情况,要删除的是头结点
if (nLoc == 0)
{
nData = m_pHead->Data;
pNODE pTemp = m_pHead;
m_pHead = m_pHead->pNext;
delete pTemp;
pTemp = nullptr;
m_nLenth--;
nError = LIST_SUCCESS;
return true;
}
//3.2正常情况,找到被删除节点的前一个节点
pNODE pPre = m_pHead;
pNODE pTemp = nullptr;
for (int i = 0; i < nLoc - 1; i++)
{
pPre = pPre->pNext;
}
//4.开始删除
pTemp = pPre->pNext;
nData = pTemp->Data;
pPre->pNext = pPre->pNext->pNext;
delete pTemp;
//5.删除成功,返回
m_nLenth--;
nError = LIST_SUCCESS;
return true;
}
//************************************************************
// 函数名称: ClearList
// 函数说明: 清空链表
// 作 者: Dylan
// 时 间: 2015/08/25
// 参 数: int & nError
// 返 回 值: bool
//************************************************************
template<class DATA>
bool CLinkList<DATA>::ClearList(int& nError)
{
//1.判断链表是否为空
if (m_nLenth == 0)
{
nError = LIST_EMPTY;
return true;
}
//2.开始清空链表
pNODE pDel = m_pHead;
pNODE pDelNext = pDel->pNext;
while (pDelNext)
{
pDel = pDelNext;
pDelNext = pDel->pNext;
delete pDel;
pDel = nullptr;
}
delete m_pHead;
m_pHead = nullptr;
m_nLenth = 0;
//3.清空完成,填写错误码,返回
nError = LIST_SUCCESS;
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
CLinkList<char> obj;
int nError;
//链表的插入
obj.ListInsert(0, 'a', nError);
obj.ListInsert(1, 'b', nError);
obj.ListInsert(2, 'c', nError);
obj.ListInsert(0, 'd', nError);
obj.PrintList();
//链表的删除
char nData = 0;
obj.ListDelete(0, nData, nError);
obj.ListDelete(2, nData, nError);
obj.PrintList();
//链表的清空
obj.ClearList(nError);
obj.PrintList();
system("pause");
return 0;
}
循环单链表:
#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;
#define LIST_SUCCESS 0
#define LIST_WRONG_LOC 1
#define LIST_EMPTY 2
template<class DATA>
class CLinkList
{
public:
CLinkList() :m_pHead(nullptr), m_nLenth(0){}
~CLinkList(){}
public:
//循环单链表
typedef struct _NODE
{
DATA Data;
_NODE* pNext;
}NODE, *pNODE;
public:
bool ListInsert( //在链表的某一个位置插入一个节点
int nLoc, //插入位置
DATA nData, //插入数据
int& nError //错误码
);
bool ListDelete( //在链表的某一个位置删除一个节点
int nLoc, //删除位置
DATA& nData, //删除数据
int& nError //错误码
);
bool ClearList( //清空链表
int& nError
);
void PrintList()
{
pNODE pTemp = m_pHead;
while (pTemp)
{
cout << pTemp->Data << " ";
pTemp = pTemp->pNext;
if (pTemp==m_pHead)
{
break;
}
}
cout << endl;
pTemp = nullptr;
}
private:
pNODE m_pHead; //头结点指针
int m_nLenth; //链表长度
};
//************************************************************
// 函数名称: ListInsert
// 函数说明: 在链表的某一个位置插入一个节点
// 作 者: Dylan
// 时 间: 2015/08/25
// 参 数: int nLoc
// 参 数: int nData
// 参 数: int & nError
// 返 回 值: bool
//************************************************************
template<class DATA>
bool CLinkList<DATA>::ListInsert(int nLoc, DATA nData, int& nError)
{
//1.判断插入位置是否正确
if (nLoc>m_nLenth)
{
nError = LIST_WRONG_LOC;
return false;
}
//2.判断头结点是否为空,为空的话,直接在头结点插入数据
if (m_pHead == nullptr)
{
m_pHead = new NODE;
m_pHead->pNext = m_pHead;
m_pHead->Data = nData;
nError = LIST_SUCCESS;
m_nLenth++;
return true;
}
//3.找到插入位置
//3.1找到插入位置的前一个节点
pNODE Pre = m_pHead;
pNODE pTemp = new NODE;
pTemp->Data = nData;
pTemp->pNext = nullptr;
for (int i = 0; i < nLoc - 1; i++)
{
Pre = Pre->pNext;
}
//3.2判断是否向头结点之前插入,处理特殊情况
if (nLoc == 0)
{
pTemp->pNext = m_pHead;
m_pHead = pTemp;
//让最后一个节点指向头结点
pTemp = pTemp->pNext;
while (pTemp->pNext!=m_pHead->pNext)
{
pTemp = pTemp->pNext;
}
pTemp->pNext = m_pHead;
nError = LIST_SUCCESS;
m_nLenth++;
return true;
}
//4.执行插入操作
pTemp->pNext = Pre->pNext;
Pre->pNext = pTemp;
//5.插入成功,返回
nError = LIST_SUCCESS;
m_nLenth++;
return true;
}
//************************************************************
// 函数名称: ListDelete
// 函数说明: 在链表的某一个位置删除一个节点,并返回被删掉的数据
// 作 者: Dylan
// 时 间: 2015/08/25
// 参 数: int nLoc
// 参 数: int & nData
// 参 数: int & nError
// 返 回 值: bool
//************************************************************
template<class DATA>
bool CLinkList<DATA>::ListDelete(int nLoc, DATA& nData, int& nError)
{
//1.判断链表是否为空
if (m_pHead == nullptr)
{
nError = LIST_EMPTY;
return false;
}
//2.判断删除位置是否错误
if (nLoc >= m_nLenth)
{
nError = LIST_WRONG_LOC;
return false;
}
//3.找到要删除的位置
//3.1特殊情况,要删除的是头结点
if (nLoc == 0)
{
nData = m_pHead->Data;
pNODE pTemp = m_pHead;
//让最后一个节点指向头结点
pTemp = m_pHead->pNext;
while (pTemp->pNext != m_pHead)
{
pTemp = pTemp->pNext;
}
pTemp->pNext = m_pHead->pNext;
pTemp = m_pHead;
m_pHead = m_pHead->pNext;
delete pTemp;
pTemp = nullptr;
m_nLenth--;
nError = LIST_SUCCESS;
return true;
}
//3.2正常情况,找到被删除节点的前一个节点
pNODE pPre = m_pHead;
pNODE pTemp = nullptr;
for (int i = 0; i < nLoc - 1; i++)
{
pPre = pPre->pNext;
}
//4.开始删除
pTemp = pPre->pNext;
nData = pTemp->Data;
pPre->pNext = pPre->pNext->pNext;
delete pTemp;
//5.删除成功,返回
m_nLenth--;
nError = LIST_SUCCESS;
return true;
}
//************************************************************
// 函数名称: ClearList
// 函数说明: 清空链表
// 作 者: Dylan
// 时 间: 2015/08/25
// 参 数: int & nError
// 返 回 值: bool
//************************************************************
template<class DATA>
bool CLinkList<DATA>::ClearList(int& nError)
{
//1.判断链表是否为空
if (m_nLenth == 0)
{
nError = LIST_EMPTY;
return true;
}
//2.开始清空链表
pNODE pDel = m_pHead;
pNODE pDelNext = pDel->pNext;
while (pDelNext&&pDelNext!=m_pHead)
{
pDel = pDelNext;
pDelNext = pDel->pNext;
delete pDel;
pDel = nullptr;
}
delete m_pHead;
m_pHead = nullptr;
pDelNext = nullptr;
m_nLenth = 0;
//3.清空完成,填写错误码,返回
nError = LIST_SUCCESS;
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
CLinkList<char> obj;
int nError;
//链表的插入
obj.ListInsert(0, 'a', nError);
obj.ListInsert(1, 'b', nError);
obj.ListInsert(2, 'c', nError);
obj.ListInsert(0, 'd', nError);
obj.PrintList();
//链表的删除
char nData = 0;
obj.ListDelete(0, nData, nError);
obj.ListDelete(2, nData, nError);
obj.PrintList();
//链表的清空
obj.ClearList(nError);
obj.PrintList();
system("pause");
return 0;
}
#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;
#define LIST_SUCCESS 0
#define LIST_WRONG_LOC 1
#define LIST_EMPTY 2
template<class DATA>
class CLinkList
{
public:
CLinkList() :m_pHead(nullptr), m_nLenth(0){}
~CLinkList(){}
public:
//双向链表
typedef struct _NODE
{
DATA Data;
_NODE* pPrev;
_NODE* pNext;
}NODE, *pNODE;
public:
bool ListInsert( //在链表的某一个位置插入一个节点
int nLoc, //插入位置
DATA nData, //插入数据
int& nError //错误码
);
bool ListDelete( //在链表的某一个位置删除一个节点
int nLoc, //删除位置
DATA& nData, //删除数据
int& nError //错误码
);
bool ClearList( //清空链表
int& nError
);
void PrintList()
{
pNODE pTemp = m_pHead;
while (pTemp)
{
cout << pTemp->Data << " ";
pTemp = pTemp->pNext;
}
cout << endl;
pTemp = nullptr;
}
private:
pNODE m_pHead; //头结点指针
int m_nLenth; //链表长度
};
//************************************************************
// 函数名称: ListInsert
// 函数说明: 在链表的某一个位置插入一个节点
// 作 者: Dylan
// 时 间: 2015/08/25
// 参 数: int nLoc
// 参 数: int nData
// 参 数: int & nError
// 返 回 值: bool
//************************************************************
template<class DATA>
bool CLinkList<DATA>::ListInsert(int nLoc, DATA nData, int& nError)
{
//1.判断插入位置是否正确
if (nLoc>m_nLenth)
{
nError = LIST_WRONG_LOC;
return false;
}
//2.判断头结点是否为空,为空的话,直接在头结点插入数据
if (m_pHead == nullptr)
{
m_pHead = new NODE;
m_pHead->pNext = nullptr;
m_pHead->pPrev = nullptr;
m_pHead->Data = nData;
nError = LIST_SUCCESS;
m_nLenth++;
return true;
}
//3.找到插入位置
//3.1找到插入位置的前一个节点
pNODE Pre = m_pHead;
pNODE pTemp = new NODE;
pTemp->Data = nData;
pTemp->pNext = nullptr;
pTemp->pPrev = nullptr;
for (int i = 0; i < nLoc - 1; i++)
{
Pre = Pre->pNext;
}
//3.2判断是否向头结点之前插入,处理特殊情况
if (nLoc == 0)
{
pTemp->pNext = m_pHead;
m_pHead->pPrev = pTemp;
m_pHead = pTemp;
nError = LIST_SUCCESS;
m_nLenth++;
return true;
}
//4.执行插入操作
pTemp->pNext = Pre->pNext;
if (Pre->pNext)
{
Pre->pNext->pPrev = pTemp;
}
pTemp->pPrev = Pre;
Pre->pNext = pTemp;
//5.插入成功,返回
nError = LIST_SUCCESS;
m_nLenth++;
return true;
}
//************************************************************
// 函数名称: ListDelete
// 函数说明: 在链表的某一个位置删除一个节点,并返回被删掉的数据
// 作 者: Dylan
// 时 间: 2015/08/25
// 参 数: int nLoc
// 参 数: int & nData
// 参 数: int & nError
// 返 回 值: bool
//************************************************************
template<class DATA>
bool CLinkList<DATA>::ListDelete(int nLoc, DATA& nData, int& nError)
{
//1.判断链表是否为空
if (m_pHead == nullptr)
{
nError = LIST_EMPTY;
return false;
}
//2.判断删除位置是否错误
if (nLoc >= m_nLenth)
{
nError = LIST_WRONG_LOC;
return false;
}
//3.找到要删除的位置
//3.1特殊情况,要删除的是头结点
if (nLoc == 0)
{
nData = m_pHead->Data;
pNODE pTemp = m_pHead;
m_pHead = m_pHead->pNext;
m_pHead->pPrev = nullptr;
delete pTemp;
pTemp = nullptr;
m_nLenth--;
nError = LIST_SUCCESS;
return true;
}
//3.2正常情况,找到被删除节点的前一个节点
pNODE pPre = m_pHead;
pNODE pTemp = nullptr;
for (int i = 0; i < nLoc - 1; i++)
{
pPre = pPre->pNext;
}
//4.开始删除
pTemp = pPre->pNext;
nData = pTemp->Data;
pPre->pNext = pPre->pNext->pNext;
if (pPre->pNext)
{
pPre->pNext->pPrev = pPre;
}
delete pTemp;
//5.删除成功,返回
m_nLenth--;
nError = LIST_SUCCESS;
return true;
}
//************************************************************
// 函数名称: ClearList
// 函数说明: 清空链表
// 作 者: Dylan
// 时 间: 2015/08/25
// 参 数: int & nError
// 返 回 值: bool
//************************************************************
template<class DATA>
bool CLinkList<DATA>::ClearList(int& nError)
{
//1.判断链表是否为空
if (m_nLenth == 0)
{
nError = LIST_EMPTY;
return true;
}
//2.开始清空链表
pNODE pDel = m_pHead;
pNODE pDelNext = pDel->pNext;
while (pDelNext)
{
pDel = pDelNext;
pDelNext = pDel->pNext;
delete pDel;
pDel = nullptr;
}
delete m_pHead;
m_pHead = nullptr;
m_nLenth = 0;
//3.清空完成,填写错误码,返回
nError = LIST_SUCCESS;
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
CLinkList<char> obj;
int nError;
//链表的插入
obj.ListInsert(0, 'a', nError);
obj.ListInsert(1, 'b', nError);
obj.ListInsert(2, 'c', nError);
obj.ListInsert(0, 'd', nError);
obj.PrintList();
//链表的删除
char nData = 0;
obj.ListDelete(0, nData, nError);
obj.ListDelete(2, nData, nError);
obj.PrintList();
//链表的清空
obj.ClearList(nError);
obj.PrintList();
system("pause");
return 0;
}