※数据结构※→☆非线性结构(tree)☆============二叉树结点 链式存储结构(tree node binary list)(二十)

来源:互联网 发布:拉客软件 编辑:程序博客网 时间:2024/06/06 19:13

二叉树

         在计算机科学中,二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用作二叉查找树和二叉堆或是二叉排序树。二叉树的每个结点至多只有二棵子树(不存在出度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2的 i -1次方个结点;深度为k的二叉树至多有2^(k) -1个结点;对任何一棵二叉树T,如果其终端结点数(即叶子结点数)为,出度为2的结点数为,则=+ 1。


基本形态
         二叉树也是递归定义的,其结点有左右子树之分,逻辑上二叉树有五种基本形态:
                  (1)空二叉树——(a);  
                  (2)只有一个根结点的二叉树——(b);
                  (3)只有左子树——(c);
                  (4)只有右子树——(d);
                  (5)完全二叉树——(e)
         注意:尽管二叉树与树有许多相似之处,但二叉树不是树的特殊情形。


重要概念
         (1)完全二叉树——若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
         (2)满二叉树——除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。
         (3)深度——二叉树的层数,就是高度。


性质
         (1) 在二叉树中,第i层的结点总数不超过2^(i-1);
         (2) 深度为h的二叉树最多有2^h-1个结点(h>=1),最少有h个结点;
         (3) 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;
         (4) 具有n个结点的完全二叉树的深度为int(log2n)+1
         (5)有N个结点的完全二叉树各结点如果用顺序方式存储,则结点之间有如下关系:
                  若I为结点编号则 如果I>1,则其父结点的编号为I/2;
                  如果2*I<=N,则其左儿子(即左子树的根结点)的编号为2*I;若2*I>N,则无左儿子;
                  如果2*I+1<=N,则其右儿子的结点编号为2*I+1;若2*I+1>N,则无右儿子。
         (6)给定N个节点,能构成h(N)种不同的二叉树。
                  h(N)为卡特兰数的第N项。h(n)=C(n,2*n)/(n+1)。
         (7)设有i个枝点,I为所有枝点的道路长度总和,J为叶的道路长度总和J=I+2i


======================================================================================================

树结点 链式存储结构(tree node list)


结点:

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

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


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


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


树结点(树节点):

        


树节点相关术语:

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

        根据树结点的相关定义,采用“双亲孩子表示法”。其属性如下:

DWORDm_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;Tm_data;//the friend class can use it directlyAL_TreeNodeList<T>*m_pParent;//Parent tree nodeAL_ListSingle<AL_TreeNodeList<T>*>m_listChild;//All Child tree node

树的几种表示法

        在实际中,可使用多种形式的存储结构来表示树,既可以采用顺序存储结构,也可以采用链式存储结构,但无论采用何种存储方式,都要求存储结构不但能存储各结点本身的数据信息,还要能唯一地反映树中各结点之间的逻辑关系。


        1.双亲表示法

                由于树中的每个结点都有唯一的一个双亲结点,所以可用一组连续的存储空间(一维数组)存储树中的各个结点,数组中的一个元素表示树中的一个结点,每个结点含两个域,数据域存放结点本身信息,双亲域指示本结点的双亲结点在数组中位置。

                


        2.孩子表示法

                1.多重链表:每个结点有多个指针域,分别指向其子树的根
                        1)结点同构:结点的指针个数相等,为树的度k,这样n个结点度为k的树必有n(k-1)+1个空链域.
                                                
                        2)结点不同构:结点指针个数不等,为该结点的度d
                                                

                2.孩子链表:每个结点的孩子结点用单链表存储,再用含n个元素的结构数组指向每个孩子链表

                


        3.双亲孩子表示法

                1.双亲表示法,PARENT(T,x)可以在常量时间内完成,但是求结点的孩子时需要遍历整个结构。
                2.孩子链表表示法,适于那些涉及孩子的操作,却不适于PARENT(T,x)操作。
                3.将双亲表示法和孩子链表表示法合在一起,可以发挥以上两种存储结构的优势,称为带双亲的孩子链表表示法

                


        4.双亲孩子兄弟表示法 (二叉树专用)

                又称为二叉树表示法,以二叉链表作为树的存储结构。

                                

                


链式存储结构
        在计算机中用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的).
        它不要求逻辑上相邻的元素在物理位置上也相邻.因此它没有顺序存储结构所具有的弱点,但也同时失去了顺序表可随机存取的优点.


        链式存储结构特点:
                1、比顺序存储结构的存储密度小 (每个节点都由数据域和指针域组成,所以相同空间内假设全存满的话顺序比链式存储更多)。
                2、逻辑上相邻的节点物理上不必相邻。
                3、插入、删除灵活 (不必移动节点,只要改变节点中的指针)。
                4、查找结点时链式存储要比顺序存储慢。
                5、每个结点是由数据域和指针域组成。


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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


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


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

        


AL_TreeNodeBinList.h

/**  @(#)$Id: AL_TreeNodeBinList.h 59 2013-09-26 03:38:35Z xiaoting $  @briefEach 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.degreedegree node: A node of the subtree containing the number is called the node degree;  2.leafleaf nodes or terminal nodes: degree 0 are called leaf nodes;  3.branchnon-terminal node or branch node: node degree is not 0;  4.parentparent node or the parent node: If a node contains a child node, this node is called its child node's parent;  5.childchild node or child node: A node subtree containing the root node is called the node's children;  6.slibingsibling nodes: nodes with the same parent node is called mutual sibling;  7.ancestorancestor node: from the root to the node through all the nodes on the branch;  8.descendantdescendant nodes: a node in the subtree rooted at any node is called the node's descendants.  ////////////////////////////////Binary Tree//////////////////////////////////////////  In computer science, a binary tree is that each node has at most two sub-trees ordered tree. Usually the root of the subtree is   called "left subtree" (left subtree) and the "right subtree" (right subtree). Binary tree is often used as a binary search tree   and binary heap or a binary sort tree. Binary tree each node has at most two sub-tree (does not exist a degree greater than two   nodes), left and right sub-tree binary tree of the points, the order can not be reversed. Binary i-th layer of at most 2 power   nodes i -1; binary tree of depth k at most 2 ^ (k) -1 nodes; for any binary tree T, if it is the terminal nodes (i.e. leaf nodes)   is, the nodes of degree 2 is, then = + 1.  ////////////////////////////////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-26 11:38:35 +0800 (周四, 26 九月 2013) $  @Revision $Revision: 59 $  @URL $URL: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_TreeNodeBinList.h $  @Header $Header: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_TreeNodeBinList.h 59 2013-09-26 03:38:35Z xiaoting $ */#ifndef CXX_AL_TREENODEBINLIST_H#define CXX_AL_TREENODEBINLIST_H#ifndef CXX_AL_LISTSINGLE_H#include "AL_ListSingle.h"#endif#ifndef CXX_AL_QUEUELIST_H#include "AL_QueueList.h"#endif/////////////////////////////////////////////////////////////////////////////AL_TreeNodeBinList///////////////////////////////////////////////////////////////////////////template<typename T> class AL_TreeBinList;template<typename T> class AL_TreeNodeBinList{public:/*** Destruction** @param* @return* @note* @attention */~AL_TreeNodeBinList();/*** GetLevel** @param* @returnDWORD* @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** @paramDWORD 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* @returnT* @note * @attention */T GetData() const;/*** SetData** @paramconst T& tTemplate <IN>* @return* @note * @attention */VOID SetData(const T& tTemplate);/*** GetParent** @param* @returnAL_TreeNodeBinList<T>** @note parent node pointer, not to manager memory* @attention */AL_TreeNodeBinList<T>*GetParent() const;/*** SetParent** @paramDWORD dwIndex <IN>* @paramAL_TreeNodeBinList<T>* pParent <IN>* @returnBOOL* @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 ) [0x00: left child, 0x01: right child]*/BOOL SetParent(DWORD dwIndex, AL_TreeNodeBinList<T>* pParent);/*** SetParentLeft** @paramAL_TreeNodeBinList<T>* pParent <IN>* @returnBOOL* @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_TreeNodeBinList<T>* pParent);/*** SetParentRight** @paramAL_TreeNodeBinList<T>* pParent <IN>* @returnBOOL* @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_TreeNodeBinList<T>* pParent);/*** Insert** @paramDWORD dwIndex <IN>* @paramAL_TreeNodeBinList<T>* pInsertChild <IN> * @returnBOOL* @note inset the const AL_TreeNodeBinList<T>*  into the child notes at the position [0x00: left child, 0x01: right child]* @attention*/BOOL Insert(DWORD dwIndex, AL_TreeNodeBinList<T>* pInsertChild);/*** InsertLeft** @paramAL_TreeNodeBinList<T>* pInsertChild <IN> * @returnBOOL* @note inset the const AL_TreeNodeBinList<T>*  into the child notes at the left* @attention*/BOOL InsertLeft(AL_TreeNodeBinList<T>* pInsertChild);/*** InsertRight** @paramAL_TreeNodeBinList<T>* pInsertChild <IN> * @returnBOOL* @note inset the const AL_TreeNodeBinList<T>*  into the child notes at the right* @attention*/BOOL InsertRight(AL_TreeNodeBinList<T>* pInsertChild);/*** Remove** @paramAL_TreeNodeBinList<T>* pRemoveChild* @returnBOOL* @note remove the notes in the child* @attention*/BOOL Remove(AL_TreeNodeBinList<T>* pRemoveChild);/*** Remove** @paramDWORD dwIndex <IN>* @returnBOOL* @note remove the child notes at the position [0x00: left child, 0x01: right child]* @attention*/BOOL Remove(DWORD dwIndex);/*** RemoveLeft** @param* @returnBOOL* @note remove the child notes at the left* @attention*/BOOL RemoveLeft();/*** RemoveRight** @param* @returnBOOL* @note remove the child notes at the right* @attention*/BOOL RemoveRight();/*** GetChildLeft** @param* @returnAL_TreeNodeBinList<T>** @note * @attention*/AL_TreeNodeBinList<T>* GetChildLeft() const;/*** GetChildRight** @param* @returnAL_TreeNodeBinList<T>** @note * @attention*/AL_TreeNodeBinList<T>* GetChildRight() const;/*** GetDegree** @param* @returnDWORD* @note degree node: A node of the subtree containing the number is called the node degree;* @attention */DWORD GetDegree() const;/*** IsLeaf** @param* @returnBOOL* @note leaf nodes or terminal nodes: degree 0 are called leaf nodes;* @attention */BOOL IsLeaf() const;/*** IsBranch** @param* @returnBOOL* @note non-terminal node or branch node: node degree is not 0;* @attention */BOOL IsBranch() const;/*** IsParent** @paramconst AL_TreeNodeBinList<T>* pChild <IN>* @returnBOOL* @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_TreeNodeBinList<T>* pChild) const;/*** GetSibling** @paramAL_ListSingle<AL_TreeNodeBinList<T>*>& listSibling <OUT>* @returnBOOL* @note sibling nodes: nodes with the same parent node is called mutual sibling;* @attention */BOOL GetSibling(AL_ListSingle<AL_TreeNodeBinList<T>*>& listSibling) const;/*** GetAncestor** @paramAL_ListSingle<AL_TreeNodeBinList<T>*>& listAncestor <OUT>* @returnBOOL* @note ancestor node: from the root to the node through all the nodes on the branch;* @attention */BOOL GetAncestor(AL_ListSingle<AL_TreeNodeBinList<T>*>& listAncestor) const;/*** GetDescendant** @paramAL_ListSingle<AL_TreeNodeBinList<T>*>& listDescendant <OUT>* @returnBOOL* @note ancestor node: from the root to the node through all the nodes on the branch;* @attention */BOOL GetDescendant(AL_ListSingle<AL_TreeNodeBinList<T>*>& listDescendant) const;protected:public:friend class AL_TreeBinList<T>;/*** Construction** @param* @return* @note private the Construction, avoid the others use it* @attention*/AL_TreeNodeBinList();/*** Construction** @paramconst T& tTemplate <IN>* @return* @note* @attention private the Construction, avoid the others use it*/AL_TreeNodeBinList(const T& tTemplate);/***Copy Construct** @paramconst AL_TreeNodeBinList<T>& cAL_TreeNodeBinList* @return*/AL_TreeNodeBinList(const AL_TreeNodeBinList<T>& cAL_TreeNodeBinList);/***Assignment** @paramconst AL_TreeNodeBinList<T>& cAL_TreeNodeBinList* @returnAL_TreeNodeBinList<T>&*/AL_TreeNodeBinList<T>& operator = (const AL_TreeNodeBinList<T>& cAL_TreeNodeBinList);public:protected:private:DWORDm_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;Tm_data;//the friend class can use it directlyAL_TreeNodeBinList<T>*m_pParent;//Parent positionAL_TreeNodeBinList<T>*m_pChildLeft;//Child tree node leftAL_TreeNodeBinList<T>*m_pChildRight;//Child tree node right};/////////////////////////////////////////////////////////////////////////////AL_TreeNodeBinList////////////////////////////////////////////////////////////////////////////*** Construction** @param* @return* @note private the Construction, avoid the others use it* @attention*/template<typename T>AL_TreeNodeBinList<T>::AL_TreeNodeBinList():m_dwLevel(0x00),m_pParent(NULL),m_pChildLeft(NULL),m_pChildRight(NULL){}/*** Construction** @paramconst T& tTemplate <IN>* @return* @note* @attention private the Construction, avoid the others use it*/template<typename T>AL_TreeNodeBinList<T>::AL_TreeNodeBinList(const T& tTemplate):m_dwLevel(0x00),m_data(tTemplate),m_pParent(NULL),m_pChildLeft(NULL),m_pChildRight(NULL){}/*** Destruction** @param* @return* @note* @attention */template<typename T>AL_TreeNodeBinList<T>::~AL_TreeNodeBinList(){//it doesn't matter to clear the pointer or not.m_dwLevel = 0x00;m_pParent = NULL;m_pChildLeft = NULL;m_pChildRight = NULL;}/*** GetLevel** @param* @returnDWORD* @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_TreeNodeBinList<T>::GetLevel() const{return m_dwLevel;}/*** SetLevel** @paramDWORD 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_TreeNodeBinList<T>::SetLevel(DWORD dwLevel){m_dwLevel = dwLevel;}/*** GetData** @param* @returnT* @note * @attention */template<typename T> T AL_TreeNodeBinList<T>::GetData() const{return m_data;}/*** SetData** @paramconst T& tTemplate <IN>* @return* @note * @attention */template<typename T> VOID AL_TreeNodeBinList<T>::SetData(const T& tTemplate){m_data = tTemplate;}/*** GetParent** @param* @returnAL_TreeNodeBinList<T>** @note parent node pointer, not to manager memory* @attention */template<typename T> AL_TreeNodeBinList<T>* AL_TreeNodeBinList<T>::GetParent() const{return m_pParent;}/*** SetParent** @paramDWORD dwIndex <IN>* @paramAL_TreeNodeBinList<T>* pParent <IN>* @returnBOOL* @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 ) [0x00: left child, 0x01: right child]*/template<typename T> BOOL AL_TreeNodeBinList<T>::SetParent(DWORD dwIndex, AL_TreeNodeBinList<T>* pParent){if (NULL == pParent) {return FALSE;}BOOL  bSetParent = FALSE;bSetParent = pParent->Insert(dwIndex, this);if (TRUE == bSetParent) {//current node insert to the parent successfullyif (NULL != m_pParent) {//current node has parentm_pParent->Remove(this);}m_pParent = pParent;}return bSetParent;}/*** SetParentLeft** @paramAL_TreeNodeBinList<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_TreeNodeBinList<T>::SetParentLeft(AL_TreeNodeBinList<T>* pParent){return SetParent(0x00, pParent);}/*** SetParentRight** @paramAL_TreeNodeBinList<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_TreeNodeBinList<T>::SetParentRight(AL_TreeNodeBinList<T>* pParent){return SetParent(0x01, pParent);}/*** Insert** @paramDWORD dwIndex <IN>* @paramAL_TreeNodeBinList<T>* pInsertChild <IN> * @returnBOOL* @note inset the const AL_TreeNodeBinList<T>*  into the child notes at the position [0x00: left child, 0x01: right child]* @attention*/template<typename T> BOOL AL_TreeNodeBinList<T>::Insert(DWORD dwIndex, AL_TreeNodeBinList<T>* pInsertChild){if (0x01 < dwIndex || NULL == pInsertChild) {return FALSE;}BOOL  bInsert = FALSE;if (0x00 == dwIndex && NULL == m_pChildLeft) {//left and the child left not existm_pChildLeft = pInsertChild;bInsert = TRUE;}else if (0x01 == dwIndex && NULL == m_pChildRight) {//right and the child right not existm_pChildRight = pInsertChild;bInsert = TRUE;}else {//no casebInsert = FALSE;}if (TRUE == bInsert) {if (GetLevel()+1 != pInsertChild->GetLevel()) {//deal with the child levelINT iLevelDiff = pInsertChild->GetLevel() - GetLevel();AL_ListSingle<AL_TreeNodeBinList<T>*> listDescendant;if (FALSE == GetDescendant(listDescendant)) {return FALSE;}AL_TreeNodeBinList<T>* pDescendant = NULL;for (DWORD dwCnt=0; dwCnt<listDescendant.Length(); dwCnt++) {if (TRUE == listDescendant.Get(pDescendant, dwCnt)) {if (NULL != pDescendant) {//set child levelpDescendant->SetLevel(pDescendant->GetLevel()-iLevelDiff+1);}else {//errorreturn FALSE;}}else {//errorreturn FALSE;}}}//child node insert to the current successfullypInsertChild->m_pParent = this;}return bInsert;}/*** InsertLeft** @paramAL_TreeNodeBinList<T>* pInsertChild <IN> * @returnBOOL* @note inset the const AL_TreeNodeBinList<T>*  into the child notes at the left* @attention*/template<typename T> BOOL AL_TreeNodeBinList<T>::InsertLeft(AL_TreeNodeBinList<T>* pInsertChild){return Insert(0x00, pInsertChild);}/*** InsertRight** @paramAL_TreeNodeBinList<T>* pInsertChild <IN> * @returnBOOL* @note inset the const AL_TreeNodeBinList<T>*  into the child notes at the right* @attention*/template<typename T> BOOL AL_TreeNodeBinList<T>::InsertRight(AL_TreeNodeBinList<T>* pInsertChild){return Insert(0x01, pInsertChild);}/*** Remove** @paramAL_TreeNodeBinList<T>* pRemoveChild* @returnBOOL* @note remove the notes in the child* @attention*/template<typename T> BOOL AL_TreeNodeBinList<T>::Remove(AL_TreeNodeBinList<T>* pRemoveChild){BOOL bRemove = FALSE;if (m_pChildLeft == pRemoveChild) {m_pChildLeft = NULL;bRemove = TRUE;}else if (m_pChildRight ==  pRemoveChild) {m_pChildRight = NULL;bRemove = TRUE;}else {bRemove = FALSE;}return bRemove;}/*** Remove** @paramDWORD dwIndex <IN>* @returnBOOL* @note remove the child notes at the position [0x00: left child, 0x01: right child]* @attention*/template<typename T> BOOL AL_TreeNodeBinList<T>::Remove(DWORD dwIndex){AL_TreeNodeBinList<T>* pRemoveChild = NULL;if (0x00 == dwIndex) {pRemoveChild = m_pChildLeft;}else if (0x01 == dwIndex) {pRemoveChild = m_pChildRight;}else {return FALSE;}return Remove(pRemoveChild);}/*** RemoveLeft** @param* @returnBOOL* @note remove the child notes at the left* @attention*/template<typename T> BOOL AL_TreeNodeBinList<T>::RemoveLeft(){return Remove(m_pChildLeft);}/*** RemoveRight** @param* @returnBOOL* @note remove the child notes at the right* @attention*/template<typename T> BOOL AL_TreeNodeBinList<T>::RemoveRight(){return Remove(m_pChildRight);}/*** GetChildLeft** @param* @returnAL_TreeNodeBinList<T>** @note * @attention*/template<typename T> AL_TreeNodeBinList<T>* AL_TreeNodeBinList<T>::GetChildLeft() const{return m_pChildLeft;}/*** GetChildRight** @param* @returnAL_TreeNodeBinList<T>** @note * @attention*/template<typename T> AL_TreeNodeBinList<T>* AL_TreeNodeBinList<T>::GetChildRight() const{return m_pChildRight;}/*** GetDegree** @param* @returnDWORD* @note degree node: A node of the subtree containing the number is called the node degree;* @attention */template<typename T> DWORD AL_TreeNodeBinList<T>::GetDegree() const{DWORD dwDegree = 0x00;if (NULL != m_pChildLeft) {dwDegree++;}if (NULL != m_pChildRight) {dwDegree++;}return dwDegree;}/*** IsLeaf** @param* @returnBOOL* @note leaf nodes or terminal nodes: degree 0 are called leaf nodes;* @attention */template<typename T> BOOL AL_TreeNodeBinList<T>::IsLeaf() const{return (0x00 == GetDegree()) ? TRUE:FALSE;}/*** IsBranch** @param* @returnBOOL* @note non-terminal node or branch node: node degree is not 0;* @attention */template<typename T> BOOL AL_TreeNodeBinList<T>::IsBranch() const{return (0x00 != GetDegree()) ? TRUE:FALSE;}/*** IsParent** @paramconst AL_TreeNodeBinList<T>* pChild <IN>* @returnBOOL* @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_TreeNodeBinList<T>::IsParent(const AL_TreeNodeBinList<T>* pChild) const{if (NULL ==  pChild) {return FALSE;}// AL_TreeNodeBinList<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;if (this == pChild->m_pParent) {return TRUE;}return FALSE;}/*** GetSibling** @paramAL_ListSingle<AL_TreeNodeBinList<T>*>& listSibling <OUT>* @returnBOOL* @note sibling nodes: nodes with the same parent node is called mutual sibling;* @attention */template<typename T> BOOLAL_TreeNodeBinList<T>::GetSibling(AL_ListSingle<AL_TreeNodeBinList<T>*>& listSibling) const{BOOL bSibling = FALSE;if (NULL == m_pParent) {//not parent nodereturn bSibling;}listSibling.Clear();AL_TreeNodeBinList<T>* pParentChild = GetChildLeft();if (NULL != pParentChild) {if (pParentChild != this) {//not itselflistSibling.InsertEnd(pParentChild);bSibling = TRUE;}}pParentChild = GetChildRight();if (NULL != pParentChild) {if (pParentChild != this) {//not itselflistSibling.InsertEnd(pParentChild);bSibling = TRUE;}}return bSibling;}/*** GetAncestor** @paramAL_ListSingle<AL_TreeNodeBinList<T>*>& listAncestor <OUT>* @returnBOOL* @note ancestor node: from the root to the node through all the nodes on the branch;* @attention */template<typename T> BOOLAL_TreeNodeBinList<T>::GetAncestor(AL_ListSingle<AL_TreeNodeBinList<T>*>& listAncestor) const{if (NULL == m_pParent) {//not parent nodereturn FALSE;}listAncestor.Clear();AL_TreeNodeBinList<T>* pParent = m_pParent;while (NULL != pParent) {listAncestor.InsertEnd(pParent);pParent = pParent->m_pParent;}return TRUE;}/*** GetDescendant** @paramAL_ListSingle<AL_TreeNodeBinList<T>*>& listDescendant <OUT>* @returnBOOL* @note ancestor node: from the root to the node through all the nodes on the branch;* @attention */template<typename T> BOOL AL_TreeNodeBinList<T>::GetDescendant(AL_ListSingle<AL_TreeNodeBinList<T>*>& listDescendant) const{if (TRUE == IsLeaf()) {//child nodereturn FALSE;}listDescendant.Clear();AL_TreeNodeBinList<T>* pDescendant = GetChildLeft();if (NULL != pDescendant) {listDescendant.InsertEnd(pDescendant);}pDescendant = GetChildRight();if (NULL != pDescendant) {listDescendant.InsertEnd(pDescendant);}//loop the all node in listDescendantDWORD dwDescendantLoop = 0x00;AL_TreeNodeBinList<T>* pDescendantLoop = NULL;while (TRUE == listDescendant.Get(pDescendant, dwDescendantLoop)) {dwDescendantLoop++;if (NULL != pDescendant) {pDescendantLoop = pDescendant->GetChildLeft();if (NULL != pDescendantLoop) {listDescendant.InsertEnd(pDescendantLoop);}pDescendantLoop = pDescendant->GetChildRight();if (NULL != pDescendantLoop) {listDescendant.InsertEnd(pDescendantLoop);}}else {//errorreturn FALSE;}}return TRUE;}/***Assignment** @paramconst AL_TreeNodeBinList<T>& cAL_TreeNodeBinList* @returnAL_TreeNodeBinList<T>&*/template<typename T> AL_TreeNodeBinList<T>& AL_TreeNodeBinList<T>::operator = (const AL_TreeNodeBinList<T>& cAL_TreeNodeBinList){m_dwLevel = cAL_TreeNodeBinList.m_dwLevel;m_data = cAL_TreeNodeBinList.m_data;m_pParent = cAL_TreeNodeBinList.m_pParent;m_pChildLeft = cAL_TreeNodeBinList.m_pChildLeft;m_pChildRight = cAL_TreeNodeBinList.m_pChildRight;return *this;}#endif // CXX_AL_TREENODEBINLIST_H/* EOF */

测试代码

#ifdef TEST_AL_TREENODEBINLISTAL_TreeNodeBinList<DWORD> cTreeNodeBinList;cTreeNodeBinList.SetLevel(1);DWORD dwLevel = cTreeNodeBinList.GetLevel();std::cout<<dwLevel<<std::endl;cTreeNodeBinList.SetData(10);DWORD dwData = cTreeNodeBinList.GetData();std::cout<<dwData<<std::endl;AL_TreeNodeBinList<DWORD> cTreeNodeBinListParent;cTreeNodeBinListParent.SetLevel(0);cTreeNodeBinListParent.SetData(0);BOOL bSetParent = cTreeNodeBinList.SetParent(0x00, &cTreeNodeBinListParent);std::cout<<bSetParent<<std::endl;AL_TreeNodeBinList<DWORD> cTreeNodeBinListChild20(20);cTreeNodeBinListChild20.SetLevel(2);AL_TreeNodeBinList<DWORD> cTreeNodeBinListChild21(21);cTreeNodeBinListChild21.SetLevel(2);AL_TreeNodeBinList<DWORD> cTreeNodeBinListChild22(22);cTreeNodeBinListChild22.SetLevel(2);AL_TreeNodeBinList<DWORD> cTreeNodeBinListChild23(23);cTreeNodeBinListChild23.SetLevel(2);BOOL bInsert = cTreeNodeBinList.Insert(0x00, &cTreeNodeBinListChild21);std::cout<<bInsert<<std::endl;bInsert = cTreeNodeBinList.InsertLeft(&cTreeNodeBinListChild20);std::cout<<bInsert<<std::endl;bInsert = cTreeNodeBinList.InsertRight(&cTreeNodeBinListChild22);std::cout<<bInsert<<std::endl;bInsert = cTreeNodeBinList.Insert(0x03, &cTreeNodeBinListChild23);std::cout<<bInsert<<std::endl;AL_TreeNodeBinList<DWORD> cTreeNodeBinListChild30(30);cTreeNodeBinListChild30.SetLevel(3);AL_TreeNodeBinList<DWORD> cTreeNodeBinListChild31(31);cTreeNodeBinListChild31.SetLevel(3);AL_TreeNodeBinList<DWORD> cTreeNodeBinListChild32(32);cTreeNodeBinListChild32.SetLevel(3);AL_TreeNodeBinList<DWORD> cTreeNodeBinListChild33(33);cTreeNodeBinListChild33.SetLevel(3);bSetParent = cTreeNodeBinListChild31.SetParent(0x00, &cTreeNodeBinListChild21);std::cout<<bSetParent<<std::endl;bSetParent = cTreeNodeBinListChild30.SetParentLeft(&cTreeNodeBinListChild21);std::cout<<bSetParent<<std::endl;bSetParent = cTreeNodeBinListChild32.SetParentRight(&cTreeNodeBinListChild21);std::cout<<bSetParent<<std::endl;bSetParent = cTreeNodeBinListChild33.SetParent(0x03, &cTreeNodeBinListChild21 );std::cout<<bSetParent<<std::endl;AL_TreeNodeBinList<DWORD>*pParent = NULL;pParent = cTreeNodeBinList.GetParent();if (NULL != pParent) {std::cout<<pParent->GetLevel()<<"    "<<pParent->GetData()<<"    "<<pParent->GetDegree()<<std::endl;std::cout<<pParent->IsLeaf()<<"    "<<pParent->IsBranch()<<"    "<<pParent->IsParent(&cTreeNodeBinList)<<"    "<<pParent->IsParent(&cTreeNodeBinListChild31)<<std::endl;}AL_TreeNodeBinList<DWORD>*pChild = NULL;pChild = cTreeNodeBinList.GetChildLeft();if (NULL != pChild) {std::cout<<pChild->GetLevel()<<"    "<<pChild->GetData()<<"    "<<pChild->GetDegree()<<std::endl;std::cout<<pChild->IsLeaf()<<"    "<<pChild->IsBranch()<<"    "<<pChild->IsParent(&cTreeNodeBinList)<<"    "<<pChild->IsParent(&cTreeNodeBinListChild31)<<std::endl;}pChild = cTreeNodeBinList.GetChildRight();if (NULL != pChild) {std::cout<<pChild->GetLevel()<<"    "<<pChild->GetData()<<"    "<<pChild->GetDegree()<<std::endl;std::cout<<pChild->IsLeaf()<<"    "<<pChild->IsBranch()<<"    "<<pChild->IsParent(&cTreeNodeBinList)<<"    "<<pChild->IsParent(&cTreeNodeBinListChild31)<<std::endl;}AL_ListSingle<AL_TreeNodeBinList<DWORD>*> cListSingle;AL_TreeNodeBinList<DWORD>*pList = NULL;BOOL bSibling = cTreeNodeBinList.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(&cTreeNodeBinList)<<"    "<<pList->IsParent(&cTreeNodeBinListChild31)<<std::endl;}}}}cListSingle.Clear();bSibling = cTreeNodeBinListChild21.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(&cTreeNodeBinList)<<"    "<<pList->IsParent(&cTreeNodeBinListChild31)<<std::endl;}}}}cListSingle.Clear();BOOL bAncestor = cTreeNodeBinListParent.GetAncestor(cListSingle);if (TRUE == bAncestor) {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(&cTreeNodeBinList)<<"    "<<pList->IsParent(&cTreeNodeBinListChild31)<<std::endl;}}}}bAncestor = cTreeNodeBinListChild32.GetAncestor(cListSingle);if (TRUE == bAncestor) {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(&cTreeNodeBinList)<<"    "<<pList->IsParent(&cTreeNodeBinListChild31)<<std::endl;}}}}cListSingle.Clear();BOOL bDescendant = cTreeNodeBinListParent.GetDescendant(cListSingle);if (TRUE == bDescendant) {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(&cTreeNodeBinList)<<"    "<<pList->IsParent(&cTreeNodeBinListChild31)<<std::endl;}}}}cListSingle.Clear();bDescendant = cTreeNodeBinListChild32.GetDescendant(cListSingle);if (TRUE == bDescendant) {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(&cTreeNodeBinList)<<"    "<<pList->IsParent(&cTreeNodeBinListChild31)<<std::endl;}}}}cListSingle.Clear();AL_TreeNodeBinList<DWORD> cTreeNodeBinListRoot(999);cTreeNodeBinListChild30.SetLevel(0);bSetParent = cTreeNodeBinListParent.SetParentLeft(&cTreeNodeBinListRoot);std::cout<<bSetParent<<std::endl;bDescendant = cTreeNodeBinListRoot.GetDescendant(cListSingle);if (TRUE == bDescendant) {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(&cTreeNodeBinList)<<"    "<<pList->IsParent(&cTreeNodeBinListChild31)<<std::endl;}}}}cListSingle.Clear();#endif






原创粉丝点击