[学习笔记]线性表的链式存储

学习线性表后,整理,记录一下方便复习。

单链表:

#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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值