zoukankan      html  css  js  c++  java
  • ※数据结构※→☆线性表结构(list)☆============单向循环链表结构(list circular single)(四)

            循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

            

            单循环链表——在单链表中,将终端结点的指针域NULL改为指向表头结点或开始结点即可。

            循环链表的特点是无须增加存储量,仅对表的链接方式稍作改变,即可使得表处理更加方便灵活。


    注意:
            ①循环链表中没有NULL指针。涉及遍历操作时,其终止条件就不再是像非循环链表那样判别p或p->next是否为空,而是判别它们是否等于某一指定指针,如头指针或尾指针等。
            ②在单链表中,从一已知结点出发,只能访问到该结点及其后续结点,无法找到该结点之前的其它结点。而在单循环链表中,从任一结点出发都可访问到表中所有结点,这一优点使某些运算在单循环链表上易于实现。



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

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

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

           


    AL_ListCircularSingle.h

    /**
      @(#)$Id: AL_ListCircularSingle.h 27 2013-09-02 07:46:27Z xiaoting $
      @brief    One-way circular list is another form of one-way linked list structure, which is characterized by a pointer to the list 
      of the last one is no longer a null value, but point to the head of the linked list. So long as we know any node in the linked list 
      can be found circulating list of all other nodes.
      
    			Singly linked list (single list) is a list, which is characterized by the direction of the chain links are unidirectional,
      Chain accessed through sequential reads starting from the head; linked list is constructed using pointers list; known the list of 
      nodes, as a linked list nodes is assembled; wherein each node has a pointer member variable refers to the next list node;
    
      @Author $Author: xiaoting $
      @Date $Date: 2013-09-02 15:46:27 +0800 (周一, 02 九月 2013) $
      @Revision $Revision: 27 $
      @URL $URL: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_ListCircularSingle.h $
      @Header $Header: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_ListCircularSingle.h 27 2013-09-02 07:46:27Z xiaoting $
     */
    
    #ifndef CXX_AL_LISTCIRCULARSINGLE_H
    #define CXX_AL_LISTCIRCULARSINGLE_H
    
    #ifndef CXX_AL_NODE_H
    #include "AL_Node.h"
    #endif
    
    ///////////////////////////////////////////////////////////////////////////
    //			AL_ListCircularSingle
    ///////////////////////////////////////////////////////////////////////////
    
    template<typename T> 
    class AL_ListCircularSingle
    {
    public:
    	static const DWORD LISTSINGLE_POSITION_INVALID		= 0xffffffff;
    	/**
    	* Construction
    	*
    	* @param
    	* @return
    	* @note
    	* @attention
    	*/
    	AL_ListCircularSingle();
    
    	/**
    	* Destruction
    	*
    	* @param
    	* @return
    	* @note
    	* @attention
    	*/
    	~AL_ListCircularSingle();
    
    	/**
    	* 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_ListCircularSingle
    ///////////////////////////////////////////////////////////////////////////
    /**
    * Construction
    *
    * @param
    * @return
    * @note
    * @attention
    */
    template<typename T> 
    AL_ListCircularSingle<T>::AL_ListCircularSingle():
    m_pHeader(NULL)
    {
    	m_pHeader = new AL_Node<T>;
    	m_pHeader->m_pNext = m_pHeader;
    }
    
    /**
    * Destruction
    *
    * @param
    * @return
    * @note
    * @attention
    */
    template<typename T> 
    AL_ListCircularSingle<T>::~AL_ListCircularSingle()
    {
    	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_ListCircularSingle<T>::Length() const
    {
    	if (TRUE == IsEmpty()) {
    		return 0;
    	}
    	AL_Node<T>* pMove = NULL;
    	DWORD dwCount = 1;
    
    	pMove = m_pHeader->m_pNext;
    	while (m_pHeader != 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_ListCircularSingle<T>::Find(const T& tTemplate ) const
    {
    	if (TRUE == IsEmpty()) {
    		return LISTSINGLE_POSITION_INVALID;
    	}
    	
    	AL_Node<T>* pMove = NULL;
    	DWORD dwCount = 1;
    
    	//loop the next data;
    	pMove = m_pHeader->m_pNext;
    	while (m_pHeader != 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 LISTSINGLE_POSITION_INVALID;
    }
    
    /**
    * IsElement
    *
    * @param const T& tTemplate 
    * @return BOOL
    * @note the tTemplate  is in the list?
    * @attention
    */
    template<typename T> BOOL 
    AL_ListCircularSingle<T>::IsElement(const T& tTemplate ) const
    {
    	if (LISTSINGLE_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_ListCircularSingle<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_pNext = m_pHeader;
    	}
    	else {
    		//among of the list
    		AL_Node<T>* pIndexNode = GetNodeByIndex(dwIndex);
    		if ((NULL == pIndexNode)) {
    			//error
    			return FALSE;
    		}
    		pInsert->m_pNext = pIndexNode;
    		pPre->m_pNext = pInsert;
    	}
    	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_ListCircularSingle<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_ListCircularSingle<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_ListCircularSingle<T>::Remove(const T& tTemplate )
    {
    	if (TRUE == IsEmpty()) {
    		return FALSE;
    	}
    
    	DWORD dwPosition = Find(tTemplate);
    	if (LISTSINGLE_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 = GetNodeByIndex(dwPosition - 1);
    	}
    
    	if (NULL == pPre) {
    		//error
    		return FALSE;
    	}
    	pPre->m_pNext = pDelete->m_pNext;
    	
    	delete pDelete;
    	pDelete = NULL;
    	return TRUE;
    }
    
    /**
    * IsEmpty
    *
    * @param
    * @return BOOL
    * @note the list has data?
    * @attention
    */
    template<typename T> BOOL 
    AL_ListCircularSingle<T>::IsEmpty() const
    {
    	return (m_pHeader == 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_ListCircularSingle<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;
    
    	/* //test code
    	T tTypeTemp;
    	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;
    	}
    
    	AL_Node<T>* pStop = pGet;
    	while(pStop != pGet->m_pNext) {
    		if (m_pHeader == pGet) {
    			//header no data
    		}
    		pGet = pGet->m_pNext;
    	}
    	*/
    }
    
    /**
    * 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_ListCircularSingle<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_ListCircularSingle<T>::Clear()
    {
    	if (TRUE == IsEmpty()) {
    		//No data,
    		return;
    	}
    
    	AL_Node<T>* pDelete = NULL;
    	while(m_pHeader != 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_ListCircularSingle<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 (m_pHeader != pMove->m_pNext) {
    		if (dwCount-1 == dwIndex) {
    			//get this place
    			return pMove;
    		}
    		dwCount ++;
    		pMove = pMove->m_pNext;
    	}
    	
    	//the end
    	return pMove;
    }
    
    #endif // CXX_AL_LISTCIRCULARSINGLE_H
    /* EOF */
    


    测试代码

    #ifdef TEST_AL_LISTCIRCULARSINGLE
    	AL_ListCircularSingle<DWORD> cListCircularSingle;
    	BOOL bEmpty = cListCircularSingle.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++)
    		cListCircularSingle.Insert(cListCircularSingle.Length(), array[i]);
    	bEmpty = cListCircularSingle.IsEmpty();
    	std::cout<<bEmpty<<std::endl;
    
    	//test the interface
    	DWORD dwListSeqLen = cListCircularSingle.Length();
    	std::cout<<dwListSeqLen<<std::endl;
    
    	DWORD dwFind = cListCircularSingle.Find(16);
    	std::cout<<dwFind<<std::endl;
    	dwFind = cListCircularSingle.Find(12);
    	std::cout<<dwFind<<std::endl;
    
    	BOOL bElement = cListCircularSingle.IsElement(16);
    	std::cout<<bElement<<std::endl;
    	bElement = cListCircularSingle.IsElement(14);
    	std::cout<<bElement<<std::endl;
    
    	BOOL bInsert = cListCircularSingle.Insert(0, 0);
    	std::cout<<bInsert<<std::endl;
    	bInsert = cListCircularSingle.Insert(16, 16);
    	std::cout<<bInsert<<std::endl;
    	bInsert = cListCircularSingle.Insert(16, 999);
    	std::cout<<bInsert<<std::endl;
    
    	BOOL bRemove = cListCircularSingle.Remove(9846354);
    	std::cout<<bRemove<<std::endl;
    	bRemove = cListCircularSingle.Remove(999);
    	std::cout<<bRemove<<std::endl;
    
    	bRemove = cListCircularSingle.Remove(10);
    	std::cout<<bRemove<<std::endl;
    
    	INT it = 0x00;
    	for (DWORD i=0; i<cListCircularSingle.Length(); i++) {
    		it = cListCircularSingle.Get(i);
    		std::cout<<it<<std::endl;
    	}
    
    	DWORD dwSet = cListCircularSingle.Set(16, 999);
    	std::cout<<dwSet<<std::endl;
    	dwSet = cListCircularSingle.Set(0, 888);
    	std::cout<<dwSet<<std::endl;
    	dwSet = cListCircularSingle.Set(11, 777);
    	std::cout<<dwSet<<std::endl;
    
    	for (DWORD i=0; i<cListCircularSingle.Length(); i++) {
    		it = cListCircularSingle.Get(i);
    		std::cout<<it<<std::endl;
    	}
    
    	cListCircularSingle.Clear();
    	bEmpty = cListCircularSingle.IsEmpty();
    	std::cout<<bEmpty<<std::endl;
    	dwListSeqLen = cListCircularSingle.Length();
    	std::cout<<dwListSeqLen<<std::endl;
    
    	bInsert = cListCircularSingle.Insert(1, 999);
    	std::cout<<bInsert<<std::endl;
    
    	bInsert = cListCircularSingle.Insert(0, 666);
    	std::cout<<bInsert<<std::endl;
    	bRemove = cListCircularSingle.Remove(666);
    	std::cout<<bRemove<<std::endl;
    	bEmpty = cListCircularSingle.IsEmpty();
    	std::cout<<bEmpty<<std::endl;
    	dwListSeqLen = cListCircularSingle.Length();
    	std::cout<<dwListSeqLen<<std::endl;
    
    #endif






  • 相关阅读:
    十的次方——挖掘并非显而易见的观点与想法
    6-3-5式脑力接龙
    三个臭皮匠,顶上一个诸葛亮——在Google Ideathon上Design Thinking分享
    上瘾:如何打造习惯养成中的产品(投资篇)
    上瘾:如何打造习惯养成中的产品(奖励篇)
    上瘾:如何打造习惯养成中的产品(行动篇)
    上瘾:如何打造习惯养成中的产品(触发器篇)
    上瘾:如何打造习惯养成中的产品
    告别2013拥抱2014
    Design Thinking Workshop @ Agile Tour 2013 Shanghai
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3299344.html
Copyright © 2011-2022 走看看