• [置顶] ※数据结构※→☆非线性结构(tree)☆============树结点 链式存储结构(tree node list)(十四)


    结点:

            包括一个数据元素及若干个指向其它子树的分支;例如,A,B,C,D等。

    在数据结构的图形表示中,对于数据集合中的每一个数据元素用中间标有元素值的方框表示,一般称之为数据结点,简称结点。


            在C语言中,链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据;二为下一个结点的地址,即指针域和数据域。


            数据结构中的每一个数据结点对应于一个储存单元,这种储存单元称为储存结点,也可简称结点


    树结点(树节点):

            


    树节点相关术语:

    • 节点的度:一个节点含有的子树的个数称为该节点的度;
    • 叶节点或终端节点:度为0的节点称为叶节点;
    • 非终端节点或分支节点:度不为0的节点;
    • 双亲节点或父节点:若一个结点含有子节点,则这个节点称为其子节点的父节点;
    • 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
    • 兄弟节点:具有相同父节点的节点互称为兄弟节点;
    • 节点的层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推;
    • 堂兄弟节点:双亲在同一层的节点互为堂兄弟;
    • 节点的祖先:从根到该节点所经分支上的所有节点;
    • 子孙:以某节点为根的子树中任一节点都称为该节点的子孙。

            根据树结点的相关定义,其属性如下:

    	DWORD								m_dwLevel;				//Node levels: starting from the root to start defining the root of the first layer, the root node is a sub-layer 2, and so on;	
    	T									m_data;					//the friend class can use it directly
    
    	AL_TreeNode<T>*						m_pParent;				//Parent tree node
    	AL_ListSingle<AL_TreeNode<T>*>		m_listChild;			//All Child tree node


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


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


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

            


    AL_TreeNode.h

    /**
      @(#)$Id: AL_TreeNode.h 44 2013-09-13 08:50:04Z xiaoting $
      @brief	Each of the data structure corresponds to a data node storage unit, this storage unit is called storage node, the node can 
      also be referred to.
    
      The related concepts of tree node 
      1.degree		degree node: A node of the subtree containing the number is called the node degree;
      2.leaf			leaf nodes or terminal nodes: degree 0 are called leaf nodes;
      3.branch		non-terminal node or branch node: node degree is not 0;
      4.parent		parent node or the parent node: If a node contains a child node, this node is called its child node's parent;
      5.child			child node or child node: A node subtree containing the root node is called the node's children;
      6.slibing		sibling nodes: nodes with the same parent node is called mutual sibling;
      7.ancestor		ancestor node: from the root to the node through all the nodes on the branch;
      8.descendant	descendant nodes: a node in the subtree rooted at any node is called the node's descendants.
    
      ////////////////////////////////Chain storage structure//////////////////////////////////////////
      The computer using a set of arbitrary linear table storage unit stores data elements (which may be a continuous plurality of memory 
      cells, it can be discontinuous).
    
      It does not require the logic elements of adjacent physical location is adjacent to and therefore it is not sequential storage 
      structure has a weakness, but also lost the sequence table can be accessed randomly advantages.
    
      Chain store structural features:
      1, compared with sequential storage density storage structure (each node consists of data fields and pointers domains, so the same 
      space is full, then assume full order of more than chain stores).
      2, the logic is not required on the adjacent node is physically adjacent.
      3, insert, delete and flexible (not the mobile node, change the node as long as the pointer).
      4, find the node when stored sequentially slower than the chain stores.
      5, each node is a pointer to the data fields and domains.
    
      @Author $Author: xiaoting $
      @Date $Date: 2013-09-13 16:50:04 +0800 (周五, 13 九月 2013) $
      @Revision $Revision: 44 $
      @URL $URL: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_TreeNode.h $
      @Header $Header: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_TreeNode.h 44 2013-09-13 08:50:04Z xiaoting $
     */
    
    #ifndef CXX_AL_TREENODE_H
    #define CXX_AL_TREENODE_H
    
    ///////////////////////////////////////////////////////////////////////////
    //			AL_TreeNode
    ///////////////////////////////////////////////////////////////////////////
    
    template<typename T> class AL_Tree;
    
    template<typename T> 
    class AL_TreeNode
    {
    public:
    	/**
    	* Destruction
    	*
    	* @param
    	* @return
    	* @note
    	* @attention 
    	*/
    	~AL_TreeNode();
    	
    	/**
    	* GetLevel
    	*
    	* @param
    	* @return	DWORD
    	* @note Node levels: starting from the root to start defining the root of the first layer, the root node is a sub-layer 2, and so on;	
    	* @attention 
    	*/
    	DWORD GetLevel() const;
    
    	/**
    	* SetLevel
    	*
    	* @param	DWORD dwLevel <IN>
    	* @return	
    	* @note Node levels: starting from the root to start defining the root of the first layer, the root node is a sub-layer 2, and so on;	
    	* @attention 
    	*/
    	VOID SetLevel(DWORD dwLevel);
    
    	/**
    	* GetData
    	*
    	* @param
    	* @return	T
    	* @note 
    	* @attention 
    	*/
    	T GetData() const;
    
    	/**
    	* SetData
    	*
    	* @param	const T& tTemplate <IN>
    	* @return	
    	* @note 
    	* @attention 
    	*/
    	VOID SetData(const T& tTemplate);
    
    	/**
    	* GetParent
    	*
    	* @param	
    	* @return	AL_TreeNode<T>*	
    	* @note parent node pointer, not to manager memory
    	* @attention 
    	*/
    	AL_TreeNode<T>*	GetParent() const;
    
    	/**
    	* SetParent
    	*
    	* @param	DWORD dwIndex <IN>
    	* @param	AL_TreeNode<T>* pParent <IN>
    	* @return	BOOL
    	* @note parent node pointer, not to manager memory
    	* @attention as the child to set the parent at the index (from the left of parent's child )
    	*/
    	BOOL SetParent(DWORD dwIndex, AL_TreeNode<T>* pParent);
    
    	/**
    	* SetParentLeft
    	*
    	* @param	AL_TreeNode<T>* pParent <IN>
    	* @return	BOOL
    	* @note parent node pointer, not to manager memory
    	* @attention as the child to set the parent at the left (from the left of parent's child )
    	*/
    	BOOL SetParentLeft(AL_TreeNode<T>* pParent);
    
    	/**
    	* SetParentRight
    	*
    	* @param	AL_TreeNode<T>* pParent <IN>
    	* @return	BOOL
    	* @note parent node pointer, not to manager memory
    	* @attention as the child to set the parent at the right (from the right of parent's child )
    	*/
    	BOOL SetParentRight(AL_TreeNode<T>* pParent);
    
    	/**
    	* Insert
    	*
    	* @param	DWORD dwIndex <IN>
    	* @param	AL_TreeNode<T>* pInsertChild <IN> 
    	* @return	BOOL
    	* @note inset the const AL_TreeNode<T>*  into the child notes at the position
    	* @attention
    	*/
    	BOOL Insert(DWORD dwIndex, AL_TreeNode<T>* pInsertChild);
    
    	/**
    	* InsertLeft
    	*
    	* @param	AL_TreeNode<T>* pInsertChild <IN> 
    	* @return	BOOL
    	* @note inset the const AL_TreeNode<T>*  into the child notes at the left
    	* @attention
    	*/
    	BOOL InsertLeft(AL_TreeNode<T>* pInsertChild);
    
    	/**
    	* InsertRight
    	*
    	* @param	AL_TreeNode<T>* pInsertChild <IN> 
    	* @return	BOOL
    	* @note inset the const AL_TreeNode<T>*  into the child notes at the right
    	* @attention
    	*/
    	BOOL InsertRight(AL_TreeNode<T>* pInsertChild);
    
    	/**
    	* GetChild
    	*
    	* @param	DWORD dwIndex <IN>
    	* @return	AL_TreeNode<T>*
    	* @note the dwIndex must is little than the node degree
    	* @attention
    	*/
    	AL_TreeNode<T>* GetChild(DWORD dwIndex) const;
    
    	/**
    	* GetChildLeft
    	*
    	* @param	
    	* @return	AL_TreeNode<T>*
    	* @note 
    	* @attention
    	*/
    	AL_TreeNode<T>* GetChildLeft() const;
    
    	/**
    	* GetChildRight
    	*
    	* @param	
    	* @return	AL_TreeNode<T>*
    	* @note 
    	* @attention
    	*/
    	AL_TreeNode<T>* GetChildRight() const;
    	
    	/**
    	* GetDegree
    	*
    	* @param
    	* @return	DWORD
    	* @note degree node: A node of the subtree containing the number is called the node degree;
    	* @attention 
    	*/
    	DWORD GetDegree() const;
    
    	/**
    	* IsLeaf
    	*
    	* @param
    	* @return	BOOL
    	* @note leaf nodes or terminal nodes: degree 0 are called leaf nodes;
    	* @attention 
    	*/
    	BOOL IsLeaf() const;
    
    	/**
    	* IsBranch
    	*
    	* @param
    	* @return	BOOL
    	* @note non-terminal node or branch node: node degree is not 0;
    	* @attention 
    	*/
    	BOOL IsBranch() const;
    
    	/**
    	* IsParent
    	*
    	* @param	const AL_TreeNode<T>* pChild <IN>
    	* @return	BOOL
    	* @note parent node or the parent node: If a node contains a child node, this node is called its child 
    	* @attention 
    	*/
    	BOOL IsParent(const AL_TreeNode<T>* pChild) const;
    
    	/**
    	* GetSibling
    	*
    	* @param	AL_ListSingle<AL_TreeNode<T>*>& listSibling <OUT>
    	* @return	BOOL
    	* @note sibling nodes: nodes with the same parent node is called mutual sibling;
    	* @attention 
    	*/
    	BOOL GetSibling(AL_ListSingle<AL_TreeNode<T>*>& listSibling) const;
    
    	/**
    	* GetAncestor
    	*
    	* @param	AL_ListSingle<AL_TreeNode<T>*>& listAncestor <OUT>
    	* @return	BOOL
    	* @note ancestor node: from the root to the node through all the nodes on the branch;
    	* @attention 
    	*/
    	BOOL GetAncestor(AL_ListSingle<AL_TreeNode<T>*>& listAncestor) const;
    
    	/**
    	* GetDescendant
    	*
    	* @param	AL_ListSingle<AL_TreeNode<T>*>& listDescendant <OUT>
    	* @return	BOOL
    	* @note ancestor node: from the root to the node through all the nodes on the branch;
    	* @attention 
    	*/
    	BOOL GetDescendant(AL_ListSingle<AL_TreeNode<T>*>& listDescendant) const;
    
    	/**
    	* Clone
    	*
    	* @param	
    	* @return	AL_TreeNode<T>*
    	* @note deep copy
    	* @attention you need to clone the all node include the descendant
    	*/
    //	AL_TreeNode<T>* Clone() const;
    
    protected:
    public:
    	friend class AL_Tree<T>;
    
    	/**
    	* Construction
    	*
    	* @param
    	* @return
    	* @note private the Construction, avoid the others use it
    	* @attention
    	*/
    	AL_TreeNode();
    	
    	/**
    	* Construction
    	*
    	* @param	const T& tTemplate <IN>
    	* @return
    	* @note
    	* @attention private the Construction, avoid the others use it
    	*/
    	AL_TreeNode(const T& tTemplate);
    
    	/**
    	*Copy Construct
    	*
    	* @param	const AL_TreeNode& cAL_TreeNode
    	* @return
    	*/
    	AL_TreeNode(const AL_TreeNode& cAL_TreeNode);
    
    	/**
    	*Assignment
    	*
    	* @param	const AL_TreeNode& cAL_TreeNode
    	* @return	AL_TreeNode&
    	*/
    	AL_TreeNode& operator = (const AL_TreeNode& cAL_TreeNode);
    
    public:
    protected:
    private:
    	DWORD								m_dwLevel;				//Node levels: starting from the root to start defining the root of the first layer, the root node is a sub-layer 2, and so on;	
    	T									m_data;					//the friend class can use it directly
    
    	AL_TreeNode<T>*						m_pParent;				//Parent tree node
    	AL_ListSingle<AL_TreeNode<T>*>		m_listChild;			//All Child tree node
    };
    
    ///////////////////////////////////////////////////////////////////////////
    //			AL_TreeNode
    ///////////////////////////////////////////////////////////////////////////
    
    /**
    * Construction
    *
    * @param
    * @return
    * @note private the Construction, avoid the others use it
    * @attention
    */
    template<typename T>
    AL_TreeNode<T>::AL_TreeNode():
    m_dwLevel(0x00),
    m_pParent(NULL)
    {
    	//memset(&m_data, 0x00, sizeof(T));		//can not use memset, as to pointer or virtural pointer of class
    	m_listChild.Clear();
    }
    
    /**
    * Construction
    *
    * @param	const T& tTemplate <IN>
    * @return
    * @note
    * @attention private the Construction, avoid the others use it
    */
    template<typename T>
    AL_TreeNode<T>::AL_TreeNode(const T& tTemplate):
    m_dwLevel(0x00),
    m_data(tTemplate),
    m_pParent(NULL)
    {
    	m_listChild.Clear();
    }
    
    
    /**
    * Destruction
    *
    * @param
    * @return
    * @note
    * @attention 
    */
    template<typename T>
    AL_TreeNode<T>::~AL_TreeNode()
    {
    	//it doesn't matter to clear the pointer or not.
    	m_dwLevel = 0x00;
    	m_listChild.Clear();
    	m_pParent = NULL;		//not to manager the memory
    }
    
    /**
    * GetLevel
    *
    * @param
    * @return	DWORD
    * @note Node levels: starting from the root to start defining the root of the first layer, the root node is a sub-layer 2, and so on;	
    * @attention 
    */
    template<typename T> DWORD 
    AL_TreeNode<T>::GetLevel() const
    {
    	return m_dwLevel;
    }
    
    /**
    * SetLevel
    *
    * @param	DWORD dwLevel <IN>
    * @return	
    * @note Node levels: starting from the root to start defining the root of the first layer, the root node is a sub-layer 2, and so on;	
    * @attention 
    */
    template<typename T> VOID 
    AL_TreeNode<T>::SetLevel(DWORD dwLevel)
    {
    	m_dwLevel = dwLevel;
    }
    
    /**
    * GetData
    *
    * @param
    * @return	T
    * @note 
    * @attention 
    */
    template<typename T> T 
    AL_TreeNode<T>::GetData() const
    {
    	return m_data;
    }
    
    /**
    * SetData
    *
    * @param	const T& tTemplate <IN>
    * @return	
    * @note 
    * @attention 
    */
    template<typename T> VOID 
    AL_TreeNode<T>::SetData(const T& tTemplate)
    {
    	m_data = tTemplate;
    }
    
    /**
    * GetParent
    *
    * @param	
    * @return	AL_TreeNode<T>*	
    * @note parent node pointer, not to manager memory
    * @attention 
    */
    template<typename T> AL_TreeNode<T>* 
    AL_TreeNode<T>::GetParent() const
    {
    	return m_pParent;
    }
    
    /**
    * SetParent
    *
    * @param	DWORD dwIndex <IN>
    * @param	AL_TreeNode<T>* pParent <IN>
    * @return	BOOL
    * @note parent node pointer, not to manager memory
    * @attention as the child to set the parent at the index (from the left of parent's child )
    */
    template<typename T> BOOL 
    AL_TreeNode<T>::SetParent(DWORD dwIndex, AL_TreeNode<T>* pParent)
    {
    	BOOL  bSetParent = FALSE;
    	bSetParent = pParent->Insert(dwIndex, this);
    	if (TRUE == bSetParent) {
    		//current node insert to the parent successfully
    		m_pParent = pParent;
    	}
    	return bSetParent;
    }
    
    /**
    * SetParentLeft
    *
    * @param	AL_TreeNode<T>* pParent <IN>
    * @return	
    * @note parent node pointer, not to manager memory
    * @attention as the child to set the parent at the left (from the left of parent's child )
    */
    template<typename T> BOOL 
    AL_TreeNode<T>::SetParentLeft(AL_TreeNode<T>* pParent)
    {
    	return SetParent(0x00, pParent);
    }
    
    /**
    * SetParentRight
    *
    * @param	AL_TreeNode<T>* pParent <IN>
    * @return	
    * @note parent node pointer, not to manager memory
    * @attention as the child to set the parent at the right (from the right of parent's child )
    */
    template<typename T> BOOL 
    AL_TreeNode<T>::SetParentRight(AL_TreeNode<T>* pParent)
    {
    	return SetParent(pParent->GetDegree(), pParent);
    }
    
    /**
    * Insert
    *
    * @param	DWORD dwIndex <IN>
    * @param	AL_TreeNode<T>* pInsertChild <IN> 
    * @return	BOOL
    * @note inset the const AL_TreeNode<T>*  into the child notes at the position
    * @attention
    */
    template<typename T> BOOL 
    AL_TreeNode<T>::Insert(DWORD dwIndex, AL_TreeNode<T>* pInsertChild)
    {
    	BOOL  bInsert = FALSE;
    	bInsert = m_listChild.Insert(dwIndex, pInsertChild);
    	if (TRUE == bInsert) {
    		//child node insert to the current successfully
    		pInsertChild->m_pParent = this;
    	}
    	return bInsert;
    }
    
    /**
    * InsertLeft
    *
    * @param	AL_TreeNode<T>* pInsertChild <IN> 
    * @return	BOOL
    * @note inset the const AL_TreeNode<T>*  into the child notes at the left
    * @attention
    */
    template<typename T> BOOL 
    AL_TreeNode<T>::InsertLeft(AL_TreeNode<T>* pInsertChild)
    {
    	return Insert(0x00, pInsertChild);
    }
    
    /**
    * InsertRight
    *
    * @param	AL_TreeNode<T>* pInsertChild <IN> 
    * @return	BOOL
    * @note inset the const AL_TreeNode<T>*  into the child notes at the right
    * @attention
    */
    template<typename T> BOOL 
    AL_TreeNode<T>::InsertRight(AL_TreeNode<T>* pInsertChild)
    {
    	return Insert(GetDegree(), pInsertChild);
    }
    
    /**
    * GetChild
    *
    * @param	DWORD dwIndex <IN>
    * @return	AL_TreeNode<T>*
    * @note the dwIndex must is little than the node degree
    * @attention
    */
    template<typename T> AL_TreeNode<T>* 
    AL_TreeNode<T>::GetChild(DWORD dwIndex) const
    {
    	AL_TreeNode<T>* pChild = NULL;
    	if (TRUE == m_listChild.Get(pChild, dwIndex)) {
    		return pChild;
    	}
    	return NULL;
    }
    
    /**
    * GetChildLeft
    *
    * @param	
    * @return	AL_TreeNode<T>*
    * @note 
    * @attention
    */
    template<typename T> AL_TreeNode<T>* 
    AL_TreeNode<T>::GetChildLeft() const
    {
    	return GetChild(0x00);
    }
    
    /**
    * GetChildRight
    *
    * @param	
    * @return	AL_TreeNode<T>*
    * @note 
    * @attention
    */
    template<typename T> AL_TreeNode<T>* 
    AL_TreeNode<T>::GetChildRight() const
    {
    	return GetChild(GetDegree());
    }
    
    /**
    * GetDegree
    *
    * @param
    * @return	DWORD
    * @note degree node: A node of the subtree containing the number is called the node degree;
    * @attention 
    */
    template<typename T> DWORD 
    AL_TreeNode<T>::GetDegree() const
    {
    	return m_listChild.Length();
    }
    
    /**
    * IsLeaf
    *
    * @param
    * @return	BOOL
    * @note leaf nodes or terminal nodes: degree 0 are called leaf nodes;
    * @attention 
    */
    template<typename T> BOOL 
    AL_TreeNode<T>::IsLeaf() const
    {
    //	return (TRUE == m_listChild.IsEmpty()) ? TRUE:FALSE;
    	return (0x00 == GetDegree()) ? TRUE:FALSE;
    }
    
    /**
    * IsBranch
    *
    * @param
    * @return	BOOL
    * @note non-terminal node or branch node: node degree is not 0;
    * @attention 
    */
    template<typename T> BOOL 
    AL_TreeNode<T>::IsBranch() const
    {
    //	return (FALSE == m_listChild.IsEmpty()) ? TRUE:FALSE;
    	return (0x00 != GetDegree()) ? TRUE:FALSE;
    }
    
    /**
    * IsParent
    *
    * @param	const AL_TreeNode<T>* pChild <IN>
    * @return	BOOL
    * @note parent node or the parent node: If a node contains a child node, this node is called its child 
    * @attention 
    */
    template<typename T> BOOL 
    AL_TreeNode<T>::IsParent(const AL_TreeNode<T>* pChild) const
    {
    	AL_TreeNode<T>* pCompare = NULL;
    	for (DWORD dwCnt=0; dwCnt<GetDegree(); dwCnt++) {
    		if (TRUE == m_listChild.Get(pCompare, dwCnt)) {
    			if (pCompare == pChild) {
    				//find the child
    				return TRUE;
    			}
    		}
    	}
    	return FALSE;
    }
    
    /**
    * GetSibling
    *
    * @param	AL_ListSingle<AL_TreeNode<T>*>& listSibling <OUT>
    * @return	BOOL
    * @note sibling nodes: nodes with the same parent node is called mutual sibling;
    * @attention 
    */
    template<typename T> BOOL
    AL_TreeNode<T>::GetSibling(AL_ListSingle<AL_TreeNode<T>*>& listSibling) const
    {
    	BOOL bSibling = FALSE;
    	if (NULL == m_pParent) {
    		//not parent node
    		return bSibling;
    	}
    	AL_ListSingle<AL_TreeNode<T>*>&	listParentChild = m_pParent->m_listChild;
    	AL_TreeNode<T>* pParentChild = NULL;
    	for (DWORD dwCnt=0; dwCnt<m_pParent->GetDegree(); dwCnt++) {
    		pParentChild = m_pParent->GetChild(dwCnt);
    		if (NULL != pParentChild) {
    			//get the child
    			if (pParentChild == this) {
    				//itself
    				continue;
    			}
    			listSibling.InsertEnd(pParentChild);
    			bSibling = TRUE;
    		}
    		else {
    			//error can not get the child
    			return FALSE;
    		}
    	}
    	return bSibling;
    }
    
    /**
    * GetAncestor
    *
    * @param	AL_ListSingle<AL_TreeNode<T>*>& listAncestor <OUT>
    * @return	BOOL
    * @note ancestor node: from the root to the node through all the nodes on the branch;
    * @attention 
    */
    template<typename T> BOOL
    AL_TreeNode<T>::GetAncestor(AL_ListSingle<AL_TreeNode<T>*>& listAncestor) const
    {
    	if (NULL == m_pParent) {
    		//not parent node
    		return FALSE;
    	}
    
    	AL_TreeNode<T>* pParent = m_pParent;
    	while (NULL != pParent) {
    		listAncestor.InsertEnd(pParent);
    		pParent = pParent->m_pParent;
    	}
    	return TRUE;
    }
    
    /**
    * GetDescendant
    *
    * @param	AL_ListSingle<AL_TreeNode<T>*>& listDescendant <OUT>
    * @return	BOOL
    * @note ancestor node: from the root to the node through all the nodes on the branch;
    * @attention 
    */
    template<typename T> BOOL 
    AL_TreeNode<T>::GetDescendant(AL_ListSingle<AL_TreeNode<T>*>& listDescendant) const
    {
    	if (TRUE == IsLeaf()) {
    		//child node
    		return FALSE;
    	}
    
    	AL_TreeNode<T>* pDescendant = NULL;
    	for (DWORD dwCnt=0; dwCnt<GetDegree(); dwCnt++) {
    		pDescendant = GetChild(dwCnt);
    		if (NULL != pDescendant) {
    			//get the child
    			listDescendant.InsertEnd(pDescendant);
    		}
    		else {
    			//error can not get the child
    			return FALSE;
    		}
    	}
    
    	//loop the all node in listDescendant
    	DWORD dwDescendantLoop = 0x00;
    	AL_TreeNode<T>* pDescendantLoop = NULL;
    	while (TRUE == listDescendant.Get(pDescendant, dwDescendantLoop)) {
    		dwDescendantLoop++;
    		if (NULL != pDescendant) {
    			for (DWORD dwCnt=0; dwCnt<pDescendant->GetDegree(); dwCnt++) {
    				pDescendantLoop = pDescendant->GetChild(dwCnt);
    				if (NULL != pDescendantLoop) {
    					//get the descendant
    					listDescendant.InsertEnd(pDescendantLoop);
    				}
    				else {
    					//error can not get the descendant
    					return FALSE;
    				}
    			}
    		}
    		else {
    			//error
    			return FALSE;
    		}
    	}
    	return TRUE;
    }
    
    /**
    * Clone
    *
    * @param	
    * @return	AL_TreeNode<T>*
    * @note deep copy
    * @attention you need to clone the all node include the descendant
    */
    // template<typename T> AL_TreeNode<T>* 
    // AL_TreeNode<T>::Clone() const
    // {
    // 	AL_TreeNode<T>* pClone = new AL_TreeNode<T>;
    // 	if (NULL == pClone) {
    // 		//new error
    // 		return NULL;
    // 	}
    // 	
    // 	AL_TreeNode<T>*						m_pChild;				//All Child tree node
    // 	AL_ListSingle<AL_TreeNode<T>*>		m_listChild;			//All Child tree node
    // 	pClone->m_dwLevel = m_dwLevel;
    // 	pClone->m_data = m_data;
    // 	pClone->m_pParent = m_pParent;
    // 	//copy the list
    // 	for (DWORD dwCloneCnt=0; dwCloneCnt<m_listChild.Length(); dwCloneCnt++) {
    // 		if (TRUE == m_listChild.Get(m_pChild, dwCloneCnt)) {
    // 			pClone->m_listChild.InsertEnd(m_pChild);			//you need to clone the all node include the descendant, not only the pointer
    // 		}
    // 	}
    // 	return pClone;
    // }
    
    #endif // CXX_AL_TREENODE_H
    /* EOF */
    


    测试代码

    #ifdef TEST_AL_AL_TREENODE
    	AL_TreeNode<DWORD> cTreeNode;
    	cTreeNode.SetLevel(1);
    	DWORD dwLevel = cTreeNode.GetLevel();
    	std::cout<<dwLevel<<std::endl;
    	cTreeNode.SetData(10);
    	DWORD dwData = cTreeNode.GetData();
    	std::cout<<dwData<<std::endl;
    	
    	AL_TreeNode<DWORD> cTreeNodeParent;
    	cTreeNodeParent.SetLevel(0);
    	cTreeNodeParent.SetData(0);
    	cTreeNode.SetParent(0x00, &cTreeNodeParent);
    	
    	AL_TreeNode<DWORD> cTreeNodeChild20(20);
    	cTreeNodeChild20.SetLevel(2);
    	AL_TreeNode<DWORD> cTreeNodeChild21(21);
    	cTreeNodeChild21.SetLevel(2);
    	AL_TreeNode<DWORD> cTreeNodeChild22(22);
    	cTreeNodeChild22.SetLevel(2);
    	AL_TreeNode<DWORD> cTreeNodeChild23(23);
    	cTreeNodeChild23.SetLevel(2);
    	cTreeNode.Insert(0x00, &cTreeNodeChild21);
    	cTreeNode.InsertLeft(&cTreeNodeChild20);
    	cTreeNode.InsertRight(&cTreeNodeChild22);
    	cTreeNode.Insert(0x03, &cTreeNodeChild23);
    
    	AL_TreeNode<DWORD> cTreeNodeChild30(30);
    	cTreeNodeChild30.SetLevel(3);
    	AL_TreeNode<DWORD> cTreeNodeChild31(31);
    	cTreeNodeChild31.SetLevel(3);
    	AL_TreeNode<DWORD> cTreeNodeChild32(32);
    	cTreeNodeChild32.SetLevel(3);
    	AL_TreeNode<DWORD> cTreeNodeChild33(33);
    	cTreeNodeChild33.SetLevel(3);
    	cTreeNodeChild31.SetParent(0x00, &cTreeNodeChild20);
    	cTreeNodeChild30.SetParentLeft(&cTreeNodeChild20);
    	cTreeNodeChild32.SetParentRight(&cTreeNodeChild20);
    	cTreeNodeChild33.SetParent(0x03, &cTreeNodeChild20 );
    
    	AL_TreeNode<DWORD>*	pParent = NULL;
    	pParent = cTreeNode.GetParent();
    	if (NULL != pParent) {
    		std::cout<<pParent->GetLevel()<<"    "<<pParent->GetData()<<"    "<<pParent->GetDegree()<<std::endl;
    		std::cout<<pParent->IsLeaf()<<"    "<<pParent->IsBranch()<<"    "<<pParent->IsParent(&cTreeNode)<<"    "<<pParent->IsParent(&cTreeNodeChild33)<<std::endl;
    	}
    
    	AL_TreeNode<DWORD>*	pChild = NULL;
    	pChild = cTreeNode.GetChild(0x01);
    	if (NULL != pChild) {
    		std::cout<<pChild->GetLevel()<<"    "<<pChild->GetData()<<"    "<<pChild->GetDegree()<<std::endl;
    		std::cout<<pChild->IsLeaf()<<"    "<<pChild->IsBranch()<<"    "<<pChild->IsParent(&cTreeNode)<<"    "<<pChild->IsParent(&cTreeNodeChild33)<<std::endl;
    	}
    	pChild = cTreeNode.GetChild(0x00);
    	if (NULL != pChild) {
    		std::cout<<pChild->GetLevel()<<"    "<<pChild->GetData()<<"    "<<pChild->GetDegree()<<std::endl;
    		std::cout<<pChild->IsLeaf()<<"    "<<pChild->IsBranch()<<"    "<<pChild->IsParent(&cTreeNode)<<"    "<<pChild->IsParent(&cTreeNodeChild33)<<std::endl;
    	}
    	pChild = cTreeNode.GetChildLeft();
    	if (NULL != pChild) {
    		std::cout<<pChild->GetLevel()<<"    "<<pChild->GetData()<<"    "<<pChild->GetDegree()<<std::endl;
    		std::cout<<pChild->IsLeaf()<<"    "<<pChild->IsBranch()<<"    "<<pChild->IsParent(&cTreeNode)<<"    "<<pChild->IsParent(&cTreeNodeChild33)<<std::endl;
    	}
    	pChild = cTreeNode.GetChild(0x03);
    	if (NULL != pChild) {
    		std::cout<<pChild->GetLevel()<<"    "<<pChild->GetData()<<"    "<<pChild->GetDegree()<<std::endl;
    		std::cout<<pChild->IsLeaf()<<"    "<<pChild->IsBranch()<<"    "<<pChild->IsParent(&cTreeNode)<<"    "<<pChild->IsParent(&cTreeNodeChild33)<<std::endl;
    	}
    	pChild = cTreeNode.GetChildRight();
    	if (NULL != pChild) {
    		std::cout<<pChild->GetLevel()<<"    "<<pChild->GetData()<<"    "<<pChild->GetDegree()<<std::endl;
    		std::cout<<pChild->IsLeaf()<<"    "<<pChild->IsBranch()<<"    "<<pChild->IsParent(&cTreeNode)<<"    "<<pChild->IsParent(&cTreeNodeChild33)<<std::endl;
    	}
    
    	AL_ListSingle<AL_TreeNode<DWORD>*> cListSingle;
    	AL_TreeNode<DWORD>*	pList = NULL;
    	BOOL bSibling = cTreeNode.GetSibling(cListSingle);
    	if (TRUE == bSibling) {
    		for (DWORD dwCnt=0; dwCnt<cListSingle.Length(); dwCnt++) {
    			if (TRUE == cListSingle.Get(pList, dwCnt)) {
    				if (NULL != pList) {
    					std::cout<<pList->GetLevel()<<"    "<<pList->GetData()<<"    "<<pList->GetDegree()<<std::endl;
    					std::cout<<pList->IsLeaf()<<"    "<<pList->IsBranch()<<"    "<<pList->IsParent(&cTreeNode)<<"    "<<pList->IsParent(&cTreeNodeChild33)<<std::endl;
    				}
    			}
    		}
    	}
    	cListSingle.Clear();
    
    	bSibling = cTreeNodeChild20.GetSibling(cListSingle);
    	if (TRUE == bSibling) {
    		for (DWORD dwCnt=0; dwCnt<cListSingle.Length(); dwCnt++) {
    			if (TRUE == cListSingle.Get(pList, dwCnt)) {
    				if (NULL != pList) {
    					std::cout<<pList->GetLevel()<<"    "<<pList->GetData()<<"    "<<pList->GetDegree()<<std::endl;
    					std::cout<<pList->IsLeaf()<<"    "<<pList->IsBranch()<<"    "<<pList->IsParent(&cTreeNode)<<"    "<<pList->IsParent(&cTreeNodeChild33)<<std::endl;
    				}
    			}
    		}
    	}
    	cListSingle.Clear();
    
    	bSibling = cTreeNodeParent.GetAncestor(cListSingle);
    	if (TRUE == bSibling) {
    		for (DWORD dwCnt=0; dwCnt<cListSingle.Length(); dwCnt++) {
    			if (TRUE == cListSingle.Get(pList, dwCnt)) {
    				if (NULL != pList) {
    					std::cout<<pList->GetLevel()<<"    "<<pList->GetData()<<"    "<<pList->GetDegree()<<std::endl;
    					std::cout<<pList->IsLeaf()<<"    "<<pList->IsBranch()<<"    "<<pList->IsParent(&cTreeNode)<<"    "<<pList->IsParent(&cTreeNodeChild33)<<std::endl;
    				}
    			}
    		}
    	}
    
    	bSibling = cTreeNodeChild33.GetAncestor(cListSingle);
    	if (TRUE == bSibling) {
    		for (DWORD dwCnt=0; dwCnt<cListSingle.Length(); dwCnt++) {
    			if (TRUE == cListSingle.Get(pList, dwCnt)) {
    				if (NULL != pList) {
    					std::cout<<pList->GetLevel()<<"    "<<pList->GetData()<<"    "<<pList->GetDegree()<<std::endl;
    					std::cout<<pList->IsLeaf()<<"    "<<pList->IsBranch()<<"    "<<pList->IsParent(&cTreeNode)<<"    "<<pList->IsParent(&cTreeNodeChild33)<<std::endl;
    				}
    			}
    		}
    	}
    	cListSingle.Clear();
    	
    	bSibling = cTreeNodeParent.GetDescendant(cListSingle);
    	if (TRUE == bSibling) {
    		for (DWORD dwCnt=0; dwCnt<cListSingle.Length(); dwCnt++) {
    			if (TRUE == cListSingle.Get(pList, dwCnt)) {
    				if (NULL != pList) {
    					std::cout<<pList->GetLevel()<<"    "<<pList->GetData()<<"    "<<pList->GetDegree()<<std::endl;
    					std::cout<<pList->IsLeaf()<<"    "<<pList->IsBranch()<<"    "<<pList->IsParent(&cTreeNode)<<"    "<<pList->IsParent(&cTreeNodeChild33)<<std::endl;
    				}
    			}
    		}
    	}
    	cListSingle.Clear();
    
    	bSibling = cTreeNodeChild33.GetDescendant(cListSingle);
    	if (TRUE == bSibling) {
    		for (DWORD dwCnt=0; dwCnt<cListSingle.Length(); dwCnt++) {
    			if (TRUE == cListSingle.Get(pList, dwCnt)) {
    				if (NULL != pList) {
    					std::cout<<pList->GetLevel()<<"    "<<pList->GetData()<<"    "<<pList->GetDegree()<<std::endl;
    					std::cout<<pList->IsLeaf()<<"    "<<pList->IsBranch()<<"    "<<pList->IsParent(&cTreeNode)<<"    "<<pList->IsParent(&cTreeNodeChild33)<<std::endl;
    				}
    			}
    		}
    	}
    	cListSingle.Clear();
    #endif








  • 相关阅读:
    sort exam
    一个简单的爬虫
    php双色球
    计算水果的总价格
    jquery三级导航,级联菜单精简
    判断学生成绩
    服务器信息展示
    服务器信息(二)一些常量名和时间戳的简单了解
    天气预报ajax+php(可惜用的是已经失效的api)
    mysql基础(二)
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3331225.html
Copyright © 2020-2023  润新知