模板链表类(QList)的封装

这几天学习了模板链表类的封装,今天记录下学习过程
模板链表类的声明和实现都要写在一个头文件中
QList.h

//模板链表类
template <class  T>
class  QList
{
public:
	QList() {
		m_bNewList = FALSE;
		m_pHead = nullptr;
		m_pEnd = nullptr;
		m_nCount = 0;
		m_bModify = FALSE;
	}

	~QList() {
		if (m_bNewList)
			ClearNode();
		else
			ClearAll();
	}
private:
	//节点类
	class Node
	{
	public:
		Node(Node* pPave, Node* pNext, T* pData)
			:m_pPave(pPave), m_pNext(pNext), m_pData(pData) {}

	private:
		Node* m_pPave;	//前一节点
		Node* m_pNext;	//下一节点
		T* m_pData;		//数据域
		friend class QList;
	};

	void ClearNode()
	{
		Node* pTem = nullptr;
		while (m_pHead)
		{
			pTem = m_pHead;
			m_pHead = m_pHead->m_pNext;

			delete pTem;
		}
		m_pHead = nullptr;
		m_pEnd = nullptr;
		m_nCount = 0;
	}

public:
	//清除链表所有的节点内存和数据域内存
	void ClearAll()
	{
		Node* pTem = nullptr;
		while (m_pHead)
		{
			pTem = m_pHead;
			m_pHead = m_pHead->m_pNext;

			delete pTem->m_pData;
			pTem->m_pData = nullptr;
			delete pTem;
			pTem = nullptr;
		}

		m_pHead = nullptr;
		m_pEnd = nullptr;
		m_nCount = 0;
	}

	int Add(T* pData)	//添加数据域指针到链表
	{
		Node* pNewNode = new Node(nullptr, nullptr, pData);
		if (m_pHead == nullptr)
		{
			m_pHead = pNewNode;
			m_pEnd = pNewNode;
		}
		else
		{
			pNewNode->m_pPave = m_pEnd;
			m_pEnd->m_pNext = pNewNode;
			m_pEnd = pNewNode;
		}

		m_nCount++;
		m_bModify = TRUE;
		return m_nCount;
	}

	T* GetAt(int nIndex)const
	{
		if (nIndex >= m_nCount || nIndex < 0)
			return nullptr;

		Node* pCur = m_pHead;

		for (int i = 0; i < nIndex; i++)
			pCur = pCur->m_pNext;

		return pCur->m_pData;
	}

	int GetCount()const
	{
		return m_nCount;
	}

	//清除修改标记
	void ClearModify() { m_bModify = FALSE; }

	BOOL GetModify()const { return m_bModify; }

	//判断空链表
	BOOL IsNull()
	{
		return m_nCount == 0;
	}

	void operator+=(T* pData)
	{
		/*Node* pNewNode = new Node(nullptr,nullptr,pData);
		pNewNode->m_pNext = m_pHead;
		pNewNode->m_pPave = nullptr;
		m_pHead->m_pPave = pNewNode;
		m_pHead = pNewNode;*/
		Add(pData);
	}

public:

	//查找单个符合条件的数据
	template<class FIND_FUNC>
	T* FindSing_if(FIND_FUNC findFunc)
	{
		Node* pCur = m_pHead;
		while (pCur)
		{
			if (findFunc(pCur->m_pData))
				return pCur->m_pData;

			pCur = pCur->m_pNext;
		}

		return nullptr;
	}

	//返回链表中所有符合指定条件的数据组成的链表指针
	//返回的链表指针用后要Delete掉
	template<class FIND_FUNC>
	QList<T>* FindAll_if(FIND_FUNC findFunc)
	{
		QList<T>* pTemList = new QList<T>;
		pTemList->m_bNewList = TRUE;

		Node* pCur = m_pHead;
		while (pCur)
		{
			if (findFunc(pCur->m_pData))
				pTemList->Add(pCur->m_pData);

			pCur = pCur->m_pNext;
		}

		return pTemList;
	}

	//删除单个符合条件的数据
	template<class DEL_FUNC>
	BOOL DelSing_if(DEL_FUNC delFunc)
	{
		Node* pCur = m_pHead;
		while (pCur)
		{
			if (delFunc(pCur->m_pData))
			{

				if (pCur == m_pHead)
				{
					//删除头节点
					m_pHead = m_pHead->m_pNext;
					m_pHead->m_pPave = nullptr;

					//删除数据域内存和节点内存,当前节点指向新的头节点
					delete pCur->m_pData;
					pCur->m_pData = nullptr;
					delete pCur;
					pCur = m_pHead;
				}
				else if (pCur == m_pEnd)
				{
					//删除尾节点
					m_pEnd = pCur->m_pPave;
					m_pEnd->m_pNext = nullptr;

					delete pCur->m_pData;
					pCur->m_pData = nullptr;
					delete pCur;
					pCur = nullptr;
				}
				else
				{
					//中间节点的删除
					Node* pNext = pCur->m_pNext;
					pCur->m_pPave->m_pNext = pCur->m_pNext;

					delete pCur->m_pData;
					pCur->m_pData = nullptr;
					delete pCur;
					pCur = pNext;
				}

				m_nCount--;
				m_bModify = TRUE;
				return 1;
			}
			else
				pCur = pCur->m_pNext;
		}

		return 0;
	}

	//删除所有符合条件的数据,返回删除的个数
	template<class DEL_FUNC>
	int DelAll_if(DEL_FUNC delFunc)
	{
		int nRet = 0;
		Node* pCur = m_pHead;
		while (pCur)
		{
			if (delFunc(pCur->m_pData))
			{

				if (pCur == m_pHead)
				{
					//删除头节点
					m_pHead = m_pHead->m_pNext;
					m_pHead->m_pPave = nullptr;

					//删除数据域内存和节点内存,当前节点指向新的头节点
					delete pCur->m_pData;
					pCur->m_pData = nullptr;
					delete pCur;
					pCur = m_pHead;
				}
				else if (pCur == m_pEnd)
				{
					//删除尾节点
					m_pEnd = pCur->m_pPave;
					m_pEnd->m_pNext = nullptr;

					delete pCur->m_pData;
					pCur->m_pData = nullptr;
					delete pCur;
					pCur = nullptr;
				}
				else
				{
					//中间节点的删除
					Node* pNext = pCur->m_pNext;
					pCur->m_pPave->m_pNext = pCur->m_pNext;

					delete pCur->m_pData;
					pCur->m_pData = nullptr;
					delete pCur;
					pCur = pNext;
				}

				m_nCount--;
				nRet++;
			}
			else
				pCur = pCur->m_pNext;
		}

		if (nRet > 0)
			m_bModify = TRUE;

		return nRet;
	}

	//修改数据
	template<class FIND_FUNC>
	void ModifyData(T* pNewData, FIND_FUNC findFunc)
	{
		Node* pCur = m_pHead;
		while (pCur)
		{
			if (findFunc(pCur->m_pData))
			{
				delete pCur->m_pData;
				pCur->m_pData = pNewData;
				m_bModify = TRUE;
				break;
			}

			pCur = pCur->m_pNext;
		}

	}

	//循环链表
	template<class FOREACH_FUNC>
	void ForEach(FOREACH_FUNC forFunc)
	{
		Node* pCur = m_pHead;
		while (pCur)
		{
			forFunc(pCur->m_pData);
			pCur = pCur->m_pNext;
		}
	}


protected:
	Node* m_pHead;		//头节点
	Node* m_pEnd;		//尾节点
	int m_nCount;		//节点个数
	BOOL m_bNewList;	//是否New的链表
	BOOL m_bModify;		//链表数据修改标记
};

我这是把函数实现也写在链表类中,当前然也可写在类外,
如:
在类内声明:

template<class FOREACH_FUNC>
void ForEachTwo(FOREACH_FUNC forFunc);

在类外实现,(要在同一头文件中)

template<class T>
template<class FOREACH_FUNC>
void QList<T>::ForEachTwo(FOREACH_FUNC forFunc)
{
	//...
}

应用实例:
1.查找指定姓名的对象,返回对象指针

TCHAR name[]=TEXT("张三");
Student* pSut=m_stuList.FindSing_if([&name](Student* p){
	return _tcscmp(p->name,name)==0;
});

2.删除指定姓名的对象

TCHAR name[]=TEXT("张三");
m_stuList.DelSing_if([&name](Student* p){
	return _tcscmp(p->name,name)==0;
});

3.链表的遍历

m_stuList.ForEach([](Student* p){
	//输出p的所有成员变量
	TCHAR strMsg[64]={0};
	_stprintf_s(strMsg,
		TEXT("编号:%d,姓名:%s,性别:%s,年龄:%d"),
		p->id,p->name,p->sex,p->age);

OutputDebugString(strMsg);//输出到输出窗口
});

你可能感兴趣的:(Win32,链表,数据结构)