自己的底层代码库(二)——双链表

今天放上双链表的实现


PS:

2013.6.5修改了容器的实现:继承了后面提到的TContainer,实现相关接口。


链表的定义TBDLinkList.h:

#ifndef _TBDLinkList_h_
#define _TBDLinkList_h_

#include <windows.h>

#include "TContainer.h"

template <class T>
class TBDLinkList;

//双向链表结点
template <class T>
struct TBDLinker
{
	TBDLinker<T> *m_pLast;	//上一个结点
	TBDLinker<T> *m_pNext;	//下一个结点
	TBDLinkList<T> *m_pLinkList;//该结点当前从属的链表
	T m_Value;			//值域

	void Init()
	{
		m_pLast = NULL;
		m_pNext = NULL;
		m_pLinkList = NULL;
	}
};

//双向链表
//该类自己不申请TBDLinker,只是负责管理外部申请的TBDLinker结点
//将其链表化,提供插入、删除功能
template <class T>
class TBDLinkList : public TContainer<T>
{
public:
	TBDLinkList();
	~TBDLinkList();

	//将pLinker加入到链表尾
	//放入结点时将对pLinker的m_pLinkList赋值this
	//成功返回true
	//参数不合法,返回false
	//pLinker本身已经有从属链表(m_pLinkList不为NULL)返回false
	bool PushTail(TBDLinker<T> *pLinker);

	//将pLinker接在pLaster的后面
	//放入结点时将对pLinker的m_pLinkList赋值this
	//成功返回true
	//参数不合法,返回false
	//pLaster不属于当前链表返回false
	//pLinker本身已经有从属链表(m_pLinkList不为NULL)返回false
	bool InsertAsNext(TBDLinker<T> *pLaster, TBDLinker<T> *pLinker);

	//将pLinker接在pNexter的前面
	//放入结点时将对pLinker的m_pLinkList赋值this
	//成功返回true
	//参数不合法,返回false
	//pNexter不属于当前链表返回false
	//pLinker本身已经有从属链表(m_pLinkList不为NULL)返回false
	bool InsertAsLast(TBDLinker<T> *pLinker, TBDLinker<T> *pNexter);

	//从链表头拿一个pLinker出来,链表中删除pLinker
	//取出结点时pLinker的m_pLinkList将被置空
	//成功返回pLinker
	//链表本身没有结点了返回NULL
	TBDLinker<T> *PopHead();

	//在链表中断开pLinker
	//断开结点时pLinker的m_pLinkList将被置空
	//成功返回true
	//参数不合法,返回false
	//结点不属于当前链表返回false
	bool Remove(TBDLinker<T> *pLinker);

	//初始化\清空链表
	void Init(ContainerFlag dwLock = enum_EnableLock);

	//获取链表头对象
	//若m_pHead为空则返回空
	T *GetHead();

	//获取链表头
	//若m_pHead为空则返回空
	TBDLinker<T> *GetHeadNode();

	//获取链表中curr的下一个对象
	//若curr为空则返回空
	//若curr不属于当前链表则返回空
	//若curr没有下一个对象则返回空
	T *GetNext(T *curr);

	//获取链表中curr对应的结点对象
	//若curr为空则返回空
	//PS:该函数不区分curr是否属于当前链表
	void *GetNode(T *curr);

private:
	TBDLinker<T> *m_pHead;//头指针
	TBDLinker<T> *m_pTail;//尾指针
};

#include "TBDLinkList.hpp"

#endif


该类设计思路与之前的单链表大致相同,需要再说明的两点:

1、增加了一个 “结点当前从属的链表”字段m_pLinkList,(1)是用来对插入链表的结点的合法性做检查,当你要插入的结点实际上已经在该链表上的时候,通过该字段的验证可以排除这种情况。(2)是当逻辑中存在多个链表对象来管理结点的情况下,比如有3个链表list1,list2,list3分别表示3种不同状态的队列,结点node会在这3个队列中(也就是在3种状态间)切换的时候,m_pLinkList可以明确的指出node当前属于哪一个队列上,或者不属于任何一个队列,不需要为了确定该结点在什么地方而做遍历。

2、结点中T m_Value的设计,当出现T需要由不用容器同时来管理的时候,比如T,在T的对象池中,空闲对象的队列希望由单链表来管理(插入删除方便),使用中对象的队列希望由AVL树来管理(查找快一点),该怎么办。这时采用的就是模版的嵌套来解决,比如 TLinker<TreeNode<T>>。


实现TBDLinkList.hpp

#ifndef _TBDLinkList_hpp_
#define _TBDLinkList_hpp_

template <class T>
TBDLinkList<T>::TBDLinkList()
{
	Init();
}

template <class T>
TBDLinkList<T>::~TBDLinkList()
{
	Init();
}

template <class T>
void TBDLinkList<T>::Init(ContainerFlag dwLock)
{
	m_pHead = NULL;
	m_pTail = NULL;
	m_dwLen = 0;
	m_dwLock = dwLock;
}

template <class T>
bool TBDLinkList<T>::PushTail(TBDLinker<T> *pLinker)
{
	bool bRes = false;

	if (NULL != pLinker)
	{
		//此处需要在下面if的外面加锁
		//因为pLinker->m_pLinkList在多线程环境下可能会变
		if (enum_EnableLock == m_dwLock)
		{
			m_csLock.Lock();
		}

		if (NULL == pLinker->m_pLinkList)
		{
			pLinker->m_pLast = m_pTail;
			pLinker->m_pNext = NULL;
			pLinker->m_pLinkList = this;

			if (NULL != m_pTail)
			{
				m_pTail->m_pNext = pLinker;
			}
			m_pTail = pLinker;

			if (NULL == m_pHead)
			{
				m_pHead = pLinker;
			}

			m_dwLen++;

			bRes = true;
		}

		if (enum_EnableLock == m_dwLock)
		{
			m_csLock.UnLock();
		}
	}

	return bRes;
}

template <class T>
bool TBDLinkList<T>::InsertAsNext(TBDLinker<T> *pLaster, TBDLinker<T> *pLinker)
{
	bool bRes = false;

	if (NULL != pLinker && NULL != pLinker)
	{
		if (enum_EnableLock == m_dwLock)
		{
			m_csLock.Lock();
		}

		if (this == pLaster->m_pLinkList && NULL == pLinker->m_pLinkList)
		{
			pLinker->m_pLast = pLaster;
			pLinker->m_pNext = pLaster->m_pNext;
			pLaster->m_pNext = pLinker;
			if (NULL != pLinker->m_pNext)
			{
				pLinker->m_pNext->m_pLast = pLinker;
			}
			pLinker->m_pLinkList = this;

			if (pLaster == m_pTail)
			{
				m_pTail = pLinker;
			}

			m_dwLen++;

			bRes = true;
		}

		if (enum_EnableLock == m_dwLock)
		{
			m_csLock.UnLock();
		}
	}

	return bRes;
}

template <class T>
bool TBDLinkList<T>::InsertAsLast(TBDLinker<T> *pLinker, TBDLinker<T> *pNexter)
{
	bool bRes = false;

	if (NULL != pLinker && NULL != pLinker)
	{
		if (enum_EnableLock == m_dwLock)
		{
			m_csLock.Lock();
		}

		if (this == pNexter->m_pLinkList && NULL == pLinker->m_pLinkList)
		{
			pLinker->m_pNext = pNexter;
			pLinker->m_pLast = pNexter->m_pLast;
			pNexter->m_pLast = pLinker;
			if (NULL != pLinker->m_pLast)
			{
				pLinker->m_pLast->m_pNext = pLinker;
			}
			pLinker->m_pLinkList = this;

			if (pNexter == m_pHead)
			{
				m_pHead = pLinker;
			}

			m_dwLen++;

			bRes = true;
		}

		if (enum_EnableLock == m_dwLock)
		{
			m_csLock.UnLock();
		}
	}

	return bRes;
}

template <class T>
TBDLinker<T> *TBDLinkList<T>::PopHead()
{
	TBDLinker<T> *pLinker = NULL;

	if (enum_EnableLock == m_dwLock)
	{
		m_csLock.Lock();
	}

	if (NULL != m_pHead)
	{
		pLinker = m_pHead;

		ResetNext(&(pLinker->m_Value));

		m_pHead = m_pHead->m_pNext;

		pLinker->m_pNext = NULL;
		pLinker->m_pLast = NULL;
		pLinker->m_pLinkList = NULL;

		if (m_pTail == pLinker)
		{
			m_pTail = NULL;
		}

		if (NULL != m_pHead)
		{
			m_pHead->m_pLast = NULL;
		}

		m_dwLen--;
	}

	if (enum_EnableLock == m_dwLock)
	{
		m_csLock.UnLock();
	}

	return pLinker;
}

template <class T>
bool TBDLinkList<T>::Remove(TBDLinker<T> *pLinker)
{
	bool bRes = false;

	if (NULL != pLinker)
	{
		if (enum_EnableLock == m_dwLock)
		{
			m_csLock.Lock();
		}

		if (this == pLinker->m_pLinkList)
		{
			ResetNext(&(pLinker->m_Value));

			if (m_pHead == pLinker)
			{
				m_pHead = pLinker->m_pNext;
			}
			if (m_pTail == pLinker)
			{
				m_pTail = pLinker->m_pLast;
			}
			if (NULL != pLinker->m_pNext)
			{
				pLinker->m_pNext->m_pLast = pLinker->m_pLast;
			}
			if (NULL != pLinker->m_pLast)
			{
				pLinker->m_pLast->m_pNext = pLinker->m_pNext;
			}
			pLinker->m_pNext = NULL;
			pLinker->m_pLast = NULL;
			pLinker->m_pLinkList = NULL;

			m_dwLen--;

			bRes = true;
		}

		if (enum_EnableLock == m_dwLock)
		{
			m_csLock.UnLock();
		}
	}

	return bRes;
}

template <class T>
T *TBDLinkList<T>::GetHead()
{
	T *pRes = NULL;

	if (enum_EnableLock == m_dwLock)
	{
		m_csLock.Lock();
	}

	if (NULL != m_pHead)
	{
		pRes = &(m_pHead->m_Value);
	}

	if (enum_EnableLock == m_dwLock)
	{
		m_csLock.UnLock();
	}

	return pRes;
}


template <class T>
TBDLinker<T> *TBDLinkList<T>::GetHeadNode()
{
	return m_pHead;
}

template <class T>
T *TBDLinkList<T>::GetNext(T *curr)
{
	T *pRes = NULL;

	if (NULL != curr)
	{
		if (enum_EnableLock == m_dwLock)
		{
			m_csLock.Lock();
		}

		TBDLinker<T> *pCurrLinker = (TBDLinker<T> *)GetNode(curr);
		if (this == pCurrLinker->m_pLinkList)
		{
			if (NULL != pCurrLinker->m_pNext)
			{
				pRes = &(pCurrLinker->m_pNext->m_Value);
			}
		}

		if (enum_EnableLock == m_dwLock)
		{
			m_csLock.UnLock();
		}
	}

	return pRes;
}

template <class T>
void *TBDLinkList<T>::GetNode(T *curr)
{
	TBDLinker<T> *pRes = NULL;

	if (NULL != curr)
	{
		pRes = ContainerOf(curr, TBDLinker<T>, m_Value);
	}

	return pRes;
}

#endif



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值