[置顶] ※数据结构※→☆线性表结构(list)☆============双向链表结构(list double)(三)

        双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。


        



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
以后的笔记潇汀会尽量详细讲解一些相关知识的,希望大家继续关注我的博客。
本节笔记到这里就结束了。




潇汀一有时间就会把自己的学习心得,觉得比较好的知识点写出来和大家一起分享。
编程开发的路很长很长,非常希望能和大家一起交流,共同学习,共同进步。
如果文章中有什么疏漏的地方,也请大家指正。也希望大家可以多留言来和我探讨编程相关的问题。
最后,谢谢你们一直的支持~~~




       C++完整个代码示例(代码在VS2005下测试可运行)

       


AL_ListDouble.h

/**
  @(#)$Id: AL_ListDouble.h 26 2013-09-02 06:38:34Z xiaoting $
  @brief    Also called double-linked list doubly linked list is a list in which each data node in both two pointers that point to a 
  direct successor and direct precursors. Therefore, two-way linked list from any one of the node point, can easily access its 
  predecessor and successor nodes node.

  @Author $Author: xiaoting $
  @Date $Date: 2013-09-02 14:38:34 +0800 (周一, 02 九月 2013) $
  @Revision $Revision: 26 $
  @URL $URL: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_ListDouble.h $
  @Header $Header: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_ListDouble.h 26 2013-09-02 06:38:34Z xiaoting $
 */

#ifndef CXX_AL_LISTDOUBLE_H
#define CXX_AL_LISTDOUBLE_H

#ifndef CXX_AL_NODE_H
#include "AL_Node.h"
#endif

///////////////////////////////////////////////////////////////////////////
//			AL_ListDouble
///////////////////////////////////////////////////////////////////////////

template<typename T> 
class AL_ListDouble
{
public:
	static const DWORD LISTDOUBLE_POSITION_INVALID		= 0xffffffff;
	/**
	* Construction
	*
	* @param
	* @return
	* @note
	* @attention
	*/
	AL_ListDouble();

	/**
	* Destruction
	*
	* @param
	* @return
	* @note
	* @attention
	*/
	~AL_ListDouble();

	/**
	* Length
	*
	* @param VOID
	* @return DWORD
	* @note get the length of the list
	* @attention
	*/
	DWORD Length() const;
	
	/**
	* Find
	*
	* @param const T& tTemplate 
	* @return DWORD
	* @note find the position of tTemplate 
	* @attention  if not find, will be return 0xffffffff
	*/
	DWORD Find(const T& tTemplate ) const;

	/**
	* IsElement
	*
	* @param const T& tTemplate 
	* @return BOOL
	* @note the tTemplate  is in the list?
	* @attention
	*/
	BOOL IsElement(const T& tTemplate ) const;

	/**
	* Insert
	*
	* @param DWORD dwIndex
	* @param const T& tTemplate 
	* @return BOOL
	* @note inset the tTemplate  into the list at the position
	* @attention
	*/
	BOOL Insert(DWORD dwIndex,const T& tTemplate );

	/**
	* InsertBegin
	*
	* @param const T& tTemplate 
	* @return BOOL
	* @note inset the tTemplate  into the list at the position
	* @attention
	*/
	BOOL InsertBegin(const T& tTemplate );


	/**
	* InsertEnd
	*
	* @param const T& tTemplate 
	* @return BOOL
	* @note inset the tTemplate  into the list at the position
	* @attention
	*/
	BOOL InsertEnd(const T& tTemplate );

	/**
	* Remove
	*
	* @param const T& tTemplate 
	* @return BOOL
	* @note remove the tTemplate  into the list
	* @attention
	*/
	BOOL Remove(const T& tTemplate );

	/**
	* IsEmpty
	*
	* @param VOID
	* @return BOOL
	* @note the list has data?
	* @attention
	*/
	BOOL IsEmpty() const;

	/**
	* Get
	*
	* @param
	* @return BOOL
	* @note get the const T& at the position
	* @attention the dwIndex must is little than the list length
	*/
	T Get(DWORD dwIndex) const;

	/**
	* Set
	*
	* @param DWORD dwIndex
	* @param const T& tTemplate 
	* @return BOOL
	* @note Replaced with the element element element on position index, and returns the old element...
	* @attention Index must in the list
	*/
	T Set(DWORD dwIndex, const T& tTemplate );

	/**
	* Clear
	*
	* @param VOID
	* @return VOID
	* @note clear the data in the list
	* @attention all data will be clear
	*/
	VOID Clear();

protected:
private:
	/**
	* GetNodeByIndex
	*
	* @param
	* @return BOOL
	* @note get the const T& at the position
	* @attention the dwIndex must is little than the list length
	*/
	AL_Node<T>* GetNodeByIndex(DWORD dwIndex) const;

public:
protected:
private: 
	AL_Node<T>*		m_pHeader;
};

///////////////////////////////////////////////////////////////////////////
//			AL_ListDouble
///////////////////////////////////////////////////////////////////////////
/**
* Construction
*
* @param
* @return
* @note
* @attention
*/
template<typename T> 
AL_ListDouble<T>::AL_ListDouble():
m_pHeader(NULL)
{
	m_pHeader = new AL_Node<T>;
}

/**
* Destruction
*
* @param
* @return
* @note
* @attention
*/
template<typename T> 
AL_ListDouble<T>::~AL_ListDouble()
{
	Clear();
	//delete the header
	delete m_pHeader;
	m_pHeader = NULL;
}

/**
* Length
*
* @param
* @return
* @note get the length of the list
* @attention
*/
template<typename T> DWORD 
AL_ListDouble<T>::Length() const
{
	if (TRUE == IsEmpty()) {
		return 0;
	}
	AL_Node<T>* pMove = NULL;
	DWORD dwCount = 1;

	pMove = m_pHeader->m_pNext;
	while (NULL != pMove->m_pNext) {
		dwCount ++;
		pMove = pMove->m_pNext;
	}
	return dwCount;
}

/**
* Find
*
* @param const T& tTemplate 
* @return DWORD
* @note find the position of tTemplate 
* @attention  if not find, will be return 0xffffffff
*/
template<typename T> DWORD 
AL_ListDouble<T>::Find(const T& tTemplate ) const
{
	if (TRUE == IsEmpty()) {
		return LISTDOUBLE_POSITION_INVALID;
	}
	
	AL_Node<T>* pMove = NULL;
	DWORD dwCount = 1;

	//loop the next data;
	pMove = m_pHeader->m_pNext;
	while (NULL != pMove->m_pNext) {
		if (tTemplate == pMove->m_data) {
			//find the data
			return dwCount-1;
		}
		dwCount ++;
		pMove = pMove->m_pNext;
	}
	
	//the end
	if (tTemplate == pMove->m_data) {
		//find the data
		return dwCount-1;
	}

	return LISTDOUBLE_POSITION_INVALID;
}

/**
* IsElement
*
* @param const T& tTemplate 
* @return BOOL
* @note the tTemplate  is in the list?
* @attention
*/
template<typename T> BOOL 
AL_ListDouble<T>::IsElement(const T& tTemplate ) const
{
	if (LISTDOUBLE_POSITION_INVALID == Find(tTemplate )) {
		return FALSE;
	}

	return TRUE;
}

/**
* Insert
*
* @param const T& tTemplate 
* @param DWORD dwIndex
* @return BOOL
* @note inset the tTemplate  into the list at the position
* @attention
*/
template<typename T> BOOL 
AL_ListDouble<T>::Insert(DWORD dwIndex, const T& tTemplate )
{
	if (dwIndex > Length()) {
		//can not insert to this position
		return FALSE;
	}
	AL_Node<T>* pInsert = new AL_Node<T>;
	pInsert->m_data = tTemplate;
	
	AL_Node<T>* pPre = NULL;
	//get the previous Node
	if (0x00 == dwIndex) {
		pPre = m_pHeader;
	}
	else {
		pPre = GetNodeByIndex(dwIndex - 1);
	}
	
	if ((NULL == pPre)) {
		//error
		return FALSE;
	}
	if (Length() == dwIndex){
		//end
		pPre->m_pNext = pInsert;
		pInsert->m_pPre = pPre;
	}
	else {
		//among of the list
		AL_Node<T>* pIndexNode = pPre->m_pNext;
		if ((NULL == pIndexNode)) {
			//error
			return FALSE;
		}
		pInsert->m_pNext = pIndexNode;
		pIndexNode->m_pPre = pInsert;

		pPre->m_pNext = pInsert;
		pInsert->m_pPre = pPre;
	}
	return TRUE;
}

/**
* InsertBegin
*
* @param const T& tTemplate 
* @return BOOL
* @note inset the tTemplate  into the list at the position
* @attention
*/
template<typename T> BOOL 
AL_ListDouble<T>::InsertBegin(const T& tTemplate )
{
	return Insert(0, tTemplate);
}

/**
* InsertEnd
*
* @param const T& tTemplate 
* @return BOOL
* @note inset the tTemplate  into the list at the position
* @attention
*/
template<typename T> BOOL 
AL_ListDouble<T>::InsertEnd(const T& tTemplate )
{
	return Insert(Length(), tTemplate);
}


/**
* Remove
*
* @param const T& tTemplate 
* @return BOOL
* @note remove the tTemplate  into the list
* @attention
*/
template<typename T> BOOL 
AL_ListDouble<T>::Remove(const T& tTemplate )
{
	if (TRUE == IsEmpty()) {
		return FALSE;
	}

	DWORD dwPosition = Find(tTemplate);
	if (LISTDOUBLE_POSITION_INVALID == dwPosition) {
		//can not find the data
		return FALSE;
	}
	
	AL_Node<T>* pDelete = GetNodeByIndex(dwPosition);
	if (NULL == pDelete) {
		//error
		return FALSE;
	}

	AL_Node<T>* pPre = NULL;
	//get the previous Node
	if (0x00 == dwPosition) {
		pPre = m_pHeader;
	}
	else {
		pPre = pDelete->m_pPre;
	}

	if (NULL == pPre) {
		//error
		return FALSE;
	}
	pPre->m_pNext = pDelete->m_pNext;

	AL_Node<T>* pNext = pDelete->m_pNext;
	if (NULL != pNext) {
		//among of the list
		pNext->m_pPre = pPre;
	}
	
	delete pDelete;
	pDelete = NULL;
	return TRUE;
}

/**
* IsEmpty
*
* @param
* @return BOOL
* @note the list has data?
* @attention
*/
template<typename T> BOOL 
AL_ListDouble<T>::IsEmpty() const
{
	return (NULL == m_pHeader->m_pNext) ? TRUE:FALSE;
}

/**
* Get
*
* @param
* @return T
* @note get the T at the position
* @attention the dwIndex must is little than the list length
*/
template<typename T> T
AL_ListDouble<T>::Get(DWORD dwIndex) const
{
	T tTypeTemp;
	memset(&tTypeTemp, 0x00, sizeof(T));

	if (TRUE == IsEmpty()) {
		//error
		return tTypeTemp;
	}

	if (Length()-1 < dwIndex) {
		//error
		return tTypeTemp;
	}
	
	AL_Node<T>* pGet = GetNodeByIndex(dwIndex);
	if (NULL == pGet) {
		//error
		return tTypeTemp;
	}
	return pGet->m_data;
}

/**
* Set
*
* @param DWORD dwIndex
* @param const T& tTemplate 
* @return T
* @note Replaced with the element element element on position index, and returns the old element...
* @attention Index must in the list
*/
template<typename T> T 
AL_ListDouble<T>::Set(DWORD dwIndex, const T& tTemplate )
{
	T tTypeTemp;
	memset(&tTypeTemp, 0x00, sizeof(T));

	if (Length()-1 < dwIndex) {
		//error
		return tTypeTemp;
	}
	
	AL_Node<T>* pSet = GetNodeByIndex(dwIndex);
	if (NULL == pSet) {
		//error
		return tTypeTemp;
	}
	
	tTypeTemp = pSet->m_data;
	pSet->m_data = tTemplate;
	return tTypeTemp;
}

/**
* Clear
*
* @param VOID
* @return VOID
* @note clear the data in the list
* @attention all data will be clear
*/
template<typename T> VOID 
AL_ListDouble<T>::Clear()
{
	if (TRUE == IsEmpty()) {
		//No data,
		return;
	}

	AL_Node<T>* pDelete = NULL;
	while(NULL != m_pHeader->m_pNext){
		//get the node
		pDelete = m_pHeader->m_pNext;
		m_pHeader->m_pNext = pDelete->m_pNext;
		delete pDelete;
		pDelete = NULL;
	}
}

/**
* GetNodeByIndex
*
* @param
* @return BOOL
* @note get the const T& at the position
* @attention the dwIndex must is little than the list length
*/
template<typename T> AL_Node<T>* 
AL_ListDouble<T>::GetNodeByIndex(DWORD dwIndex) const
{
	if (Length()-1 < dwIndex) {
		//error
		return NULL;
	}

	AL_Node<T>* pMove = NULL;
	DWORD dwCount = 1;
	//loop the next data;
	pMove = m_pHeader->m_pNext;
	while (NULL != pMove->m_pNext) {
		if (dwCount-1 == dwIndex) {
			//get this place
			return pMove;
		}
		dwCount ++;
		pMove = pMove->m_pNext;
	}
	
	//the end
	return pMove;

	/*
	//forward loop (only for test)
	//get the end node
	AL_Node<T>* pEnd = NULL;
	AL_Node<T>* pMove = NULL;
	//loop the next data;
	pMove = m_pHeader->m_pNext;
	while (NULL != pMove->m_pNext) {
		pMove = pMove->m_pNext;
	}
	pEnd = pMove;
	pMove = NULL;

	DWORD dwCount = Length();
	//loop the next data;
	pMove = pEnd;
	while (m_pHeader != pMove->m_pPre) {
		if (dwCount-1 == dwIndex) {
			//get this place
			return pMove;
		}
		dwCount --;
		pMove = pMove->m_pPre;
	}

	//the end
	return pMove;
	*/
}

#endif // CXX_AL_LISTDOUBLE_H
/* EOF */


测试代码

#ifdef TEST_AL_LISTDOUBLE
	AL_ListDouble<DWORD> cListDouble;
	BOOL bEmpty = cListDouble.IsEmpty();
	std::cout<<bEmpty<<std::endl;

	int array[15]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
	for(int i=0;i<15;i++)
		cListDouble.Insert(cListDouble.Length(), array[i]);
	bEmpty = cListDouble.IsEmpty();
	std::cout<<bEmpty<<std::endl;

	//test the interface
	DWORD dwListSeqLen = cListDouble.Length();
	std::cout<<dwListSeqLen<<std::endl;

	DWORD dwFind = cListDouble.Find(16);
	std::cout<<dwFind<<std::endl;
	dwFind = cListDouble.Find(12);
	std::cout<<dwFind<<std::endl;

	BOOL bElement = cListDouble.IsElement(16);
	std::cout<<bElement<<std::endl;
	bElement = cListDouble.IsElement(14);
	std::cout<<bElement<<std::endl;

	BOOL bInsert = cListDouble.Insert(0, 0);
	std::cout<<bInsert<<std::endl;
	bInsert = cListDouble.Insert(16, 16);
	std::cout<<bInsert<<std::endl;
	bInsert = cListDouble.Insert(16, 999);
	std::cout<<bInsert<<std::endl;

	BOOL bRemove = cListDouble.Remove(9846354);
	std::cout<<bRemove<<std::endl;
	bRemove = cListDouble.Remove(999);
	std::cout<<bRemove<<std::endl;

	bRemove = cListDouble.Remove(10);
	std::cout<<bRemove<<std::endl;

	INT it = 0x00;
	for (DWORD i=0; i<cListDouble.Length(); i++) {
		it = cListDouble.Get(i);
		std::cout<<it<<std::endl;
	}

	DWORD dwSet = cListDouble.Set(16, 999);
	std::cout<<dwSet<<std::endl;
	dwSet = cListDouble.Set(0, 888);
	std::cout<<dwSet<<std::endl;
	dwSet = cListDouble.Set(11, 777);
	std::cout<<dwSet<<std::endl;

	for (DWORD i=0; i<cListDouble.Length(); i++) {
		it = cListDouble.Get(i);
		std::cout<<it<<std::endl;
	}

	cListDouble.Clear();
	bEmpty = cListDouble.IsEmpty();
	std::cout<<bEmpty<<std::endl;
	dwListSeqLen = cListDouble.Length();
	std::cout<<dwListSeqLen<<std::endl;

	bInsert = cListDouble.Insert(1, 999);
	std::cout<<bInsert<<std::endl;

	bInsert = cListDouble.Insert(0, 666);
	std::cout<<bInsert<<std::endl;
	bRemove = cListDouble.Remove(666);
	std::cout<<bRemove<<std::endl;
	bEmpty = cListDouble.IsEmpty();
	std::cout<<bEmpty<<std::endl;
	dwListSeqLen = cListDouble.Length();
	std::cout<<dwListSeqLen<<std::endl;
#endif	


原文地址:https://www.cnblogs.com/riskyer/p/3297341.html