数据结构-二叉树 C和C++实现

二叉树,指针域具有两个“下一节点域”的特殊链表结构。

先来看看它的结构

来看程序中需要使用到的概念:

1、基本概念:

树根:二叉树的第一个节点,如图“10”为树根,也叫根节点

子树:对于某一个节点指针域指向的节点,左指针指向的节点为左子节点,右指针指向的节点为右子节点

树高:树的层数,如图树高为3

树宽:树在最多节点一层的节点数,如图树宽为4

叶子:不具有子树的节点,如图有4个叶子,分别为8、7、5、4

2、树的形态:

满二叉树:每一层上的节点数都是当层的最大节点数的二叉树,如上图为一颗满二叉树。

完全二叉树:对于一颗满二叉树,从右往左删除它的叶子节点,那么任意这样子的树都称为完全二叉树。若图中橙色的“4”删除掉,则为完全二叉树。

3、遍历方法:

先序遍历:按照“根->左子树->右子树”的顺序遍历数据。如图遍历顺序为(黑色数字):10,9,8,7,6,5,4

中序遍历:按照“左子树->根->右子树”的顺序遍历数据。如图遍历顺序为(黑色数字):8,9,7,10,5,6,4

后序遍历:按照“左子树->右子树->根”的顺序遍历数据。如图遍历顺序为(黑色数字):8,7,9,5,4,6,10




 

C语言版本

C语言版本测试中用开头图中的例子:

如图这棵树有7个节点,红色数字为节点编号,圆圈内黑色数字为节点的值。

包含BiTreeNode、BinaryTree、Queue三个部分。main中为测试程序。

BiTreeNode为数的节点操作、BinaryTree为树本身的操作。Queue只用于统计宽度。

树的重要程序文件:

BiTreeNode.c:

#include <string.h>
#include "BiTreeNode.h"



bool BiTreeNode_Reset(BiTreeNode *node,int index, TreeElem data);
bool BiTreeNode_Delete(BiTreeNode *node);
int BiTreeNode_getIndex(BiTreeNode *node);
TreeElem BiTreeNode_getData(BiTreeNode *node);
BiTreeNode *BiTreeNode_getParent(BiTreeNode *node);
BiTreeNode *BiTreeNode_getLChild(BiTreeNode *node);
BiTreeNode *BiTreeNode_getRChild(BiTreeNode *node);
bool BiTreeNode_setIndex(BiTreeNode *node,int index);
bool BiTreeNode_setData(BiTreeNode *node,TreeElem data);
bool BiTreeNode_setParenet(BiTreeNode *node,BiTreeNode *parent);
bool BiTreeNode_setLChild(BiTreeNode *node,BiTreeNode *child);
bool BiTreeNode_setRChild(BiTreeNode *node,BiTreeNode *child);

BiTreeNode *BiTreeNode_NodeSearch(BiTreeNode *node,int index);
int NodeLeavesStatistics(BiTreeNode *Node,int leaves);//统计叶子数
int NodeChildrenNodeHeigh(BiTreeNode *Node); //统计子节点的最大高度(包含本节点)/(以本节点作为根求树的高度)

void BiTreeNode_PreorderTraversal(BiTreeNode *node);
void BiTreeNode_InorderTraversal(BiTreeNode *node);
void BiTreeNode_SubsequentTraversal(BiTreeNode *node);


bool BiTreeNode_Reset(BiTreeNode *node,int index, TreeElem data)
{
    if(node == NULL)
    {
         return false;//please malloc first.
    }
    node->iIndex = index;
    node->tData = data;
    node->pParent = NULL;
    node->pLeftChild = NULL;
    node->pRightChild = NULL;
    return true;
}

bool BiTreeNode_Delete(BiTreeNode *node)
{
    if(node == NULL)
    {
        return false;
    }
    if(node->pLeftChild != NULL)
    {
        BiTreeNode_Delete(node->pLeftChild);
        node->pLeftChild = NULL;
    }
    if(node->pRightChild != NULL)
    {
        BiTreeNode_Delete(node->pRightChild);
        node->pRightChild = NULL;        
    }
    node->pParent = NULL;
    free(node);
    return true;
}

int BiTreeNode_getIndex(BiTreeNode *node)
{
    return node->iIndex;
}

TreeElem BiTreeNode_getData(BiTreeNode *node)
{
    return node->tData;
}

BiTreeNode *BiTreeNode_getParent(BiTreeNode *node)
{
    return node->pParent;
}
BiTreeNode *BiTreeNode_getLChild(BiTreeNode *node)
{
    return node->pLeftChild;
}
BiTreeNode *BiTreeNode_getRChild(BiTreeNode *node)
{
    return node->pRightChild;
}
bool BiTreeNode_setIndex(BiTreeNode *node,int index)
{
    if(node == NULL)
    {
        return false;
    }

    node->iIndex = index;
    return true;
}
bool BiTreeNode_setData(BiTreeNode *node,TreeElem data)
{
    if(node==NULL)
    {
        return false;
    }

    node->tData = data;
    return true;
}
bool BiTreeNode_setParenet(BiTreeNode *node,BiTreeNode *parent)
{
    node->pParent = parent;
    return true;
}
bool BiTreeNode_setLChild(BiTreeNode *node,BiTreeNode *child)
{
    node->pLeftChild = child;
    return true;
}
bool BiTreeNode_setRChild(BiTreeNode *node,BiTreeNode *child)
{
    node->pRightChild = child;
    return true;
}

BiTreeNode *BiTreeNode_NodeSearch(BiTreeNode *node,int index)
{
    BiTreeNode  *tempNode = NULL;
    if(node->iIndex == index)
    {
        return node;
    }
    if(node->pLeftChild != NULL)
    {
        tempNode = BiTreeNode_NodeSearch(node->pLeftChild,index);
        if(tempNode != NULL)
        {
            return tempNode;
        }
    }
    if(node->pRightChild != NULL)
    {
        tempNode = BiTreeNode_NodeSearch(node->pRightChild,index);
        if(tempNode != NULL)
        {
            return tempNode;
        }
    }
    return NULL;
}

int NodeLeavesStatistics(BiTreeNode *Node,int leaves)//统计叶子数
{
    if(Node->pLeftChild != NULL)
    {
        leaves = NodeLeavesStatistics(Node->pLeftChild,leaves);
    }
    if(Node->pRightChild != NULL)
    {
        leaves = NodeLeavesStatistics(Node->pRightChild,leaves);
    }
    if(Node->pLeftChild == NULL && Node->pRightChild == NULL)
    {
        leaves ++;
    }
    return leaves;        
}

int NodeChildrenNodeHeigh(BiTreeNode *Node) //统计子节点的最大高度(包含本节点)/(以本节点作为根求树的高度)
{
    int heightLeft =0 ;
    int heightRight =0; 
    if(Node->pLeftChild != NULL)
    {
        heightLeft += NodeChildrenNodeHeigh(Node->pLeftChild);    
    }
    if(Node->pRightChild != NULL)
    {
        heightRight += NodeChildrenNodeHeigh(Node->pRightChild);
    }
    if(heightRight > heightLeft)
    {
        return ++heightRight;
    }
    else
    {
        return ++heightLeft;
    }    
}

int NodeChildrenStatistics(BiTreeNode *node)//统计子节点数(包括本节点)
{
    int iCnt=0;
    if(node->pLeftChild != NULL)
    {
        iCnt+=NodeChildrenStatistics(node->pLeftChild);
    }
    if(node->pRightChild!= NULL)
    {
        iCnt+=NodeChildrenStatistics(node->pRightChild);;
    }
    iCnt++;
    return iCnt;    
}

//traversal
void BiTreeNode_PreorderTraversal(BiTreeNode *node)
{
    printf("Index:%d,Data:%d\r\n",node->iIndex ,node->tData);

    if(node->pLeftChild != NULL)
    {
        BiTreeNode_PreorderTraversal(node->pLeftChild);
    }

    if(node->pRightChild != NULL)
    {
        BiTreeNode_PreorderTraversal(node->pRightChild);
    }
}
void BiTreeNode_InorderTraversal(BiTreeNode *node)
{
    if(node->pLeftChild != NULL)
    {
        BiTreeNode_InorderTraversal(node->pLeftChild);
    }

    printf("Index:%d,Data:%d\r\n",node->iIndex ,node->tData);

    if(node->pRightChild != NULL)
    {
        BiTreeNode_InorderTraversal(node->pRightChild);
    }
}
void BiTreeNode_SubsequentTraversal(BiTreeNode *node)
{
    if(node->pLeftChild != NULL)
    {
        BiTreeNode_SubsequentTraversal(node->pLeftChild);
    }

    if(node->pRightChild != NULL)
    {
        BiTreeNode_SubsequentTraversal(node->pRightChild);
    }

    printf("Index:%d,Data:%d\r\n",node->iIndex ,node->tData);
}
View Code

BiTreeNode.h:

#ifndef _BITREENODE_H
#define _BITREENODE_H
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "Mystdbool.h"


typedef int TreeElem;

/*节点定义*/
typedef struct bitreenode
{
    TreeElem tData;
    int iIndex;
    struct bitreenode *pParent;
    struct bitreenode *pLeftChild;
    struct bitreenode *pRightChild;
}BiTreeNode;

//create and delete
bool BiTreeNode_Reset(BiTreeNode *node,int index ,TreeElem data);
bool BiTreeNode_Delete(BiTreeNode *node);
//get
int BiTreeNode_getIndex(BiTreeNode *node);
TreeElem BiTreeNode_getData(BiTreeNode *node);
BiTreeNode *BiTreeNode_getParent(BiTreeNode *node);
BiTreeNode *BiTreeNode_getLChild(BiTreeNode *node);
BiTreeNode *BiTreeNode_getRChild(BiTreeNode *node);
//set
bool BiTreeNode_setIndex(BiTreeNode *node,int index);
bool BiTreeNode_setData(BiTreeNode *node,TreeElem data);
bool BiTreeNode_setParenet(BiTreeNode *node,BiTreeNode *parent);
bool BiTreeNode_setLChild(BiTreeNode *node,BiTreeNode *child);
bool BiTreeNode_setRChild(BiTreeNode *node,BiTreeNode *child);
//search and statistics
BiTreeNode *BiTreeNode_NodeSearch(BiTreeNode *node,int index);
int NodeLeavesStatistics(BiTreeNode *Node,int leaves);//统计叶子数
int NodeChildrenNodeHeigh(BiTreeNode *Node); //统计子节点的最大高度(包含本节点)/(以本节点作为根求树的高度)
int NodeChildrenStatistics(BiTreeNode *node);//统计子节点数(包括本节点)
//Traversal
void BiTreeNode_PreorderTraversal(BiTreeNode *node);
void BiTreeNode_InorderTraversal(BiTreeNode *node);
void BiTreeNode_SubsequentTraversal(BiTreeNode *node);
#endif
View Code

 

BinaryTree.c

#include "BinaryTree.h"

bool BinaryTreeCreate(BinaryTree *tree,int size,int rootdata);
bool BinaryTreeDelete(BinaryTree *tree);
bool IsTreeFull(BinaryTree *tree);
//search and statistics
BiTreeNode* getNodeByIndex(BinaryTree *tree,int index);
int getLeaves(BinaryTree *tree);
int getHeight(BinaryTree *tree);
int getWidth(BinaryTree *tree);
int getTreeNodeNumber(BinaryTree *tree);
int getTreeMaxCapacity(BinaryTree *tree);
//add and delete
bool addLeftNodeByNode(BinaryTree *tree,int index,TreeElem data,BiTreeNode *pNode);    //添加左子树(使用父节点地址)  
bool addRightNodeByNode(BinaryTree *tree,int index,TreeElem data,BiTreeNode *pNode);     //添加右子树(使用父节点地址)
bool addLeftNodeByIndex(BinaryTree *tree,int newIndex,TreeElem data,int searchIndex);    //添加左子树(使用索引)
bool addRightNodeByIndex(BinaryTree *tree,int newIndex,TreeElem data,int searchIndex);   //添加右子树(使用索引)
bool deleteNodeByNode(BinaryTree *tree,BiTreeNode *pNode);
bool deleteNodeByIndex(BinaryTree *tree,int index);    
//traversal
void PreorderTraversal(BinaryTree *tree);                                            //先序遍历
void InorderTraversal(BinaryTree *tree)    ;                                            //中序遍历
void SubsequentTraversal(BinaryTree *tree);                                            //后序遍历

//create
bool BinaryTreeCreate(BinaryTree *tree,int size,int rootdata)
{
    tree->iMaxSize = size;
    tree->iSize=1;
    tree->pRoot = (BiTreeNode *)malloc(sizeof(BiTreeNode));
    BiTreeNode_Reset(tree->pRoot,1,rootdata);
    //tree->pRoot->pLeftChild = 0;
    //tree->pRoot->pRightChild = 0;
    //tree->pRoot->pParent = 0;
    return true;
}
bool BinaryTreeDelete(BinaryTree *tree)
{
    if(tree->pRoot == NULL)
    {
        return false;
    }
    deleteNodeByNode(tree,tree->pRoot);
    return true;
}



bool IsTreeFull(BinaryTree *tree)
{
    if(tree->iSize >= tree->iMaxSize)
        return true;
    return false;
}


//search and statics
/*******************************************************/
/*******************************************************/
/**********************节点搜索*************************/
/*******************************************************/
/*******************************************************/
BiTreeNode* getNodeByIndex(BinaryTree *tree,int index)
{
    return BiTreeNode_NodeSearch(tree->pRoot,index);    
}
/*******************************************************/
/*******************************************************/
/**********************叶子统计*************************/
/*******************************************************/
/*******************************************************/
int getLeaves(BinaryTree *tree)
{
    return NodeLeavesStatistics(tree->pRoot,0);
}

/*******************************************************/
/*******************************************************/
/**********************高度统计*************************/
/*******************************************************/
/*******************************************************/
int getHeight(BinaryTree *tree)
{
    return NodeChildrenNodeHeigh(tree->pRoot);
}
/*******************************************************/
/*******************************************************/
/**********************宽度统计*************************/
/*******************************************************/
/*******************************************************/
int getWidth(BinaryTree *tree)
{
    int maxWidth=1;                //save max width
    int parentWidth=0;            //save this width
    int childrenWidth=0;        //save next width
    BiTreeNode *tempNode = tree->pRoot;
    Queue *myQueue = (Queue*)malloc(sizeof(Queue));

    //create queue
    Queue_Create(myQueue,30);

    if(tempNode -> pLeftChild != NULL)
    {
        Queue_push(myQueue,tempNode -> pLeftChild);
        parentWidth ++;
    }
    if(tempNode -> pRightChild != NULL)
    {
        Queue_push(myQueue,tempNode ->pRightChild);
        parentWidth ++;
    }

    while(!isQueueEmpty(myQueue))
    {
        while(parentWidth>0)
        {
            tempNode = Queue_front(myQueue);
            Queue_pop(myQueue);
            if(tempNode -> pLeftChild != NULL)
            {
                Queue_push(myQueue , tempNode -> pLeftChild);
                childrenWidth ++;
            }
            if(tempNode -> pRightChild != NULL)
            {
                Queue_push(myQueue , tempNode -> pRightChild);
                childrenWidth ++;
            }
            parentWidth --;
        }
        parentWidth = childrenWidth;
        if(parentWidth > maxWidth)
        {
            maxWidth = parentWidth;
        }
        childrenWidth =0;
    }

    Queue_Delete(myQueue);
    myQueue = NULL;

    return maxWidth;    
}
/****************************************************************************************/ 
//name:      getTreeNowSize(BinaryTree *tree)
//describ:   You will get how much node that the tree has.
//called:     
//input:     tree:tree address; index:new node 
//output:    Number of nodes
/****************************************************************************************/
int getTreeNowSize(BinaryTree *tree)
{
    //quickly search
    //return tree->iSize;

    return NodeChildrenStatistics(tree->pRoot);
}
/****************************************************************************************/ 
//name:      getTreeNodeNumber(BinaryTree *tree)
//describ:   You will get the maximum capacity of the tree.
//called:     
//input:     tree:tree address; index:new node 
//output:    Tree capacity
/****************************************************************************************/
int getTreeMaxCapacity(BinaryTree *tree)
{
    return tree->iMaxSize;
}

//add/delete
/****************************************************************************************/ 
//name:      addLeftNodeByNode(BinaryTree *tree,int index,TreeElem data,BiTreeNode *pNode) 
//describ:   adding a left child to pNode in tree.
//called:     
//input:     tree:tree address; index:new node index; data:new node data; pNode:father node
//output:    true/false
/****************************************************************************************/
bool addLeftNodeByNode(BinaryTree *tree,int index,TreeElem data,BiTreeNode *pNode)    //添加左子树(使用父节点地址)  
{
    BiTreeNode *pNodeCopy = pNode;//To make a copy of pNode  protect that is accidentally changed. 
    BiTreeNode *newNode = NULL;
    if(IsTreeFull(tree))
    {
        return false ;
    }
    if(BiTreeNode_getLChild(pNodeCopy) == NULL)
    {
        newNode = (BiTreeNode *)malloc(sizeof(BiTreeNode));
        BiTreeNode_Reset(newNode,index,data);
        BiTreeNode_setLChild(pNodeCopy,newNode);
        BiTreeNode_setParenet(newNode,pNodeCopy);
    }
    else 
    {
        return false ;
    }

    tree->iSize++;
    return true;    
}
bool addRightNodeByNode(BinaryTree *tree,int index,TreeElem data,BiTreeNode *pNode)     //添加右子树(使用父节点地址)
{
    BiTreeNode *pNodeCopy = pNode;//To make a copy of pNode  protect that is accidentally changed. 
    BiTreeNode *newNode = NULL;
    if(IsTreeFull(tree))
    {
        return false ;
    }
    if(BiTreeNode_getRChild(pNodeCopy) == NULL)
    {
        newNode = (BiTreeNode *)malloc(sizeof(BiTreeNode));
        BiTreeNode_Reset(newNode,index,data);
        BiTreeNode_setRChild(pNodeCopy,newNode);
        BiTreeNode_setParenet(newNode,pNodeCopy);
    }
    else 
    {
        return false ;
    }

    tree->iSize++;
    return true;        
}
bool addLeftNodeByIndex(BinaryTree *tree,int newIndex,TreeElem data,int searchIndex)//添加左子树(使用索引)
{
    BiTreeNode *tempNode;
    tempNode = getNodeByIndex(tree,searchIndex);//find the Node witch is index = searchIndex
    if(tempNode!=NULL)
    {
        return addLeftNodeByNode(tree,newIndex,data,tempNode);
    }
    return false;    
}
bool addRightNodeByIndex(BinaryTree *tree,int newIndex,TreeElem data,int searchIndex)   //添加右子树(使用索引)
{
    BiTreeNode *tempNode;
    tempNode = getNodeByIndex(tree,searchIndex);//find the Node witch is index = searchIndex
    if(tempNode!=NULL)
    {
        return addRightNodeByNode(tree,newIndex,data,tempNode);
    }
    return false;    
}
/****************************************************************************************/ 
//name:      deleteNodeByIndex(BinaryTree *tree,int index)    
//describ:   to delete child tree by index
//called:     
//input:     tree:tree address; index:new node index;
//output:    true/false
/****************************************************************************************/
bool deleteNodeByNode(BinaryTree *tree,BiTreeNode *pNode)                          //删除节点及其子节点(使用地址)
{
    BiTreeNode *parentNode = NULL;
    int nodeCNT;
    if(pNode != NULL && pNode != tree->pRoot)
    {
        /*Statistics*/
        nodeCNT=NodeChildrenStatistics(pNode);
        /*clear parent Node L/RChild*/
        parentNode= BiTreeNode_getParent(pNode);
        if(parentNode != NULL)
        {
            if(BiTreeNode_getLChild(parentNode) == pNode)
            {
                BiTreeNode_setLChild(parentNode,NULL);
            }
            else
            {
                BiTreeNode_setRChild(parentNode,NULL);
            }
        }

        /*Its all children and it will be deleted*/
        BiTreeNode_Delete(pNode);
        tree->iSize -=nodeCNT;
        return true;
    }
    return false;
}

bool deleteNodeByIndex(BinaryTree *tree,int index)                              //删除节点及其子节点(使用索引)
{
    BiTreeNode *deleteNode = getNodeByIndex(tree,index);
    if(deleteNode != NULL)
    {
        if(deleteNode == tree->pRoot)//rute can't not be delete
        {
            return false;
        }

        deleteNodeByNode(tree,deleteNode);
        return true;
    }
    return false;
}


//traversal
void PreorderTraversal(BinaryTree *tree)                                            //先序遍历
{
    printf("PreorderTraversal:\r\n");
    BiTreeNode_PreorderTraversal(tree->pRoot);
}

void InorderTraversal(BinaryTree *tree)                                                //中序遍历
{
    printf("InorderTraversal:\r\n");
    BiTreeNode_InorderTraversal(tree->pRoot);
}

void SubsequentTraversal(BinaryTree *tree)                                            //后序遍历
{
    printf("SubsequentTraversal:\r\n");
    BiTreeNode_SubsequentTraversal(tree->pRoot);
}
View Code

BinaryTree.h

#ifndef _BINARYTREE_H
#define _BINARYTREE_H
#include <stdlib.h>
#include "Mystdbool.h"
#include "Queue.h"
#include "BiTreeNode.h"
/*树定义*/
typedef struct binarytree
{
    BiTreeNode *pRoot;
    int iSize;
    int iMaxSize;
}BinaryTree;
//public
//create
bool BinaryTreeCreate(BinaryTree *tree,int size,int rootdata);
bool BinaryTreeDelete(BinaryTree *tree);
bool IsTreeFull(BinaryTree *tree);
//search and statistics
BiTreeNode* getNodeByIndex(BinaryTree *tree,int index);
int getLeaves(BinaryTree *tree);
int getHeight(BinaryTree *tree);
int getWidth(BinaryTree *tree);
int getTreeNowSize(BinaryTree *tree);
int getTreeMaxCapacity(BinaryTree *tree);
//add and delete
bool addLeftNodeByNode(BinaryTree *tree,int index,TreeElem data,BiTreeNode *pNode);    //添加左子树(使用父节点地址)  
bool addRightNodeByNode(BinaryTree *tree,int index,TreeElem data,BiTreeNode *pNode);     //添加右子树(使用父节点地址)
bool addLeftNodeByIndex(BinaryTree *tree,int newIndex,TreeElem data,int searchIndex);    //添加左子树(使用索引)
bool addRightNodeByIndex(BinaryTree *tree,int newIndex,TreeElem data,int searchIndex);   //添加右子树(使用索引)
bool deleteNodeByNode(BinaryTree *tree,BiTreeNode *pNode);
bool deleteNodeByIndex(BinaryTree *tree,int index);    
//traversal
void PreorderTraversal(BinaryTree *tree);                                            //先序遍历
void InorderTraversal(BinaryTree *tree)    ;                                            //中序遍历
void SubsequentTraversal(BinaryTree *tree);                                            //后序遍历

//private
bool IsTreeFull(BinaryTree *tree);
#endif
View Code

 

其他需要使用的关联文件

Queue.c:

#include <stdlib.h>
#include <stdio.h>
#include "Queue.h"


/*******************************************************/
/*******************************************************/
/**********************创建队列*************************/
/*******************************************************/
/*******************************************************/
bool Queue_Create(Queue *queue,int size)
{
    if(queue == NULL)
    {
        queue = malloc(sizeof(Queue));        
    }
    
    queue->iSize = size;
    queue->iLength = 0;
    queue->iTail=0;
    queue->iHead=0;
    queue->Datas = (ElemQueue *)malloc(size*sizeof(ElemQueue));
    return true;
}
/*******************************************************/
/*******************************************************/
/**********************删除队列*************************/
/*******************************************************/
/*******************************************************/
bool Queue_Delete(Queue *queue)
{
    free(queue->Datas);
    return true;
}
/*******************************************************/
/*******************************************************/
/*********************队头队尾操作**********************/
/*******************************************************/
/*******************************************************/
static void QueueTailAdd(Queue *queue)
{
    queue->iTail++;
    queue->iTail = queue->iTail % queue->iSize;
}
static void QueueHeadAdd(Queue *queue)
{
    queue->iHead ++;
    queue->iHead = queue->iHead % queue->iSize;
}
/*******************************************************/
/*******************************************************/
/***********************队列判空************************/
/*******************************************************/
/*******************************************************/
bool isQueueEmpty(Queue *queue)
{
    if(queue->iLength == 0)
    {
        return true;
    }
    return false;    
}
/*******************************************************/
/*******************************************************/
/***********************队列判满************************/
/*******************************************************/
/*******************************************************/
bool isQueueFull(Queue *queue)
{
    if(queue->iLength>=queue->iSize)
    {
        return true;
    }
    return false;
}
/*******************************************************/
/*******************************************************/
/*******************返回队列现有长度********************/
/*******************************************************/
/*******************************************************/
int Queue_size(Queue *queue)
{
    return queue->iLength;
}
/*******************************************************/
/*******************************************************/
/********************往队尾放入元素*********************/
/*******************************************************/
/*******************************************************/
bool Queue_push(Queue *queue,ElemQueue data)
{
    if(isQueueFull(queue))
    {
        return 0;
    }

    queue->Datas[queue->iTail] = data; 
    QueueTailAdd(queue);
    queue->iLength++;
    return true;
}
/*******************************************************/
/*******************************************************/
/************获取队头第一个元素(不删除)***************/
/*******************************************************/
/*******************************************************/
ElemQueue Queue_front(Queue *queue)
{
    if(isQueueEmpty(queue))
    {
        return 0;
    }

    return queue->Datas[queue->iHead];
}
ElemQueue Queue_back(Queue *queue)
{
    if(isQueueEmpty (queue))
    {
        return 0;
    }
    return queue->Datas[queue->iTail];
}
/*******************************************************/
/*******************************************************/
/******************删除队列第一个元素*******************/
/*******************************************************/
/*******************************************************/
bool Queue_pop(Queue *queue)
{
    if(isQueueEmpty(queue))
    {
        return false;//queue empty
    }

    QueueHeadAdd(queue);
    queue->iLength--;
    return true;
}
/*******************************************************/
/*******************************************************/
/*****************打印队列中的全部元素******************/
/*******************************************************/
/*******************************************************/
void Queue_printf(Queue *queue)
{
    int i;
    int temp = queue->iHead;
    printf("queue datas:\r\n");
    for(i=0;i<queue->iLength;i++)
    {
        printf("%d ",queue->Datas[temp++%queue->iSize]);
    }

}
View Code

Queue.h:

#ifndef _QUEUE_H
#define _QUEUE_H
#include "BinaryTree.h"
#include "Mystdbool.h"


typedef  struct bitreenode *ElemQueue;
//#define ElemQueue struct bitreenode*

typedef struct circlequeue
{
    int iLength;
    int iSize;
    int iHead;
    int iTail;
    ElemQueue (*Datas); 
}Queue;


bool Queue_Create(Queue *queue,int size);
bool Queue_Delete(Queue *queue);
bool isQueueEmpty(Queue *queue);
bool isQueueFull(Queue *queue);
int Queue_size(Queue *queue);
bool Queue_push(Queue *queue,ElemQueue data);
ElemQueue Queue_front(Queue *queue);
ElemQueue Queue_back(Queue *queue);
bool Queue_pop(Queue *queue);
void Queue_printf(Queue *queue);

#endif
View Code

 

Mystdbool.h(用于声明bool)

#ifndef __MYSTDBOOL_H
#define __MYSTDBOOL_H


typedef enum Bool
{
    false=0,
    true,
}bool;






#endif
View Code

 

main.c(用于测试)

#include <stdlib.h>
#include <stdio.h>
#include "BinaryTree.h"


int main(void)
{
    BinaryTree tree={0};
    BinaryTreeCreate(&tree,7,10);
    //first level
    addLeftNodeByIndex(&tree,2,9,1);
    addRightNodeByIndex(&tree,3,6,1);
    //second level
    addLeftNodeByIndex(&tree,4,8,2);
    addRightNodeByIndex(&tree,5,7,2);
    addLeftNodeByIndex(&tree,6,5,3);
    addRightNodeByIndex(&tree,7,4,3);

    PreorderTraversal(&tree);
    InorderTraversal(&tree);
    SubsequentTraversal(&tree);

    printf("leaves:%d\r\n",getLeaves(&tree));
    printf("height:%d\r\n",getHeight(&tree));
    printf("width:%d\r\n",getWidth(&tree));
    printf("Nodes:%d\r\n",getTreeNowSize(&tree));

    system("pause");
    return 0;
}

运行结果:

 





 

C++版本

程序源码

本程序包含三部分

BinaryTree.h中为树的操作

BinaryTreeNode.h中为节点的操作

main.c中程序用于测试

BiTreeNode.h:

#ifndef _BITREENODE_H
#define _BITREENODE_H
#include<iostream>
using namespace std;


template <typename T>
class BiTreeNode
{
public:
    BiTreeNode();
    BiTreeNode(int index,T data);
    virtual ~BiTreeNode();
    //get data
    int getIndex();
    T getData();
    BiTreeNode *getParent();
    BiTreeNode *getLChild();
    BiTreeNode *getRChild();
    BiTreeNode *getInorderPrecursor();                    //获取中序前驱
    BiTreeNode *getInorderSubsequence();                //获取中序后继
    //set data
    void setIndex(int index);
    void setData(T data);
    void setParenet(BiTreeNode *Node);
    void setLChild(BiTreeNode *Node);
    void setRChild(BiTreeNode *Node);
    //else
    BiTreeNode *NodeSearch(int index);                    //通过索引搜索节点(以本节点作为根寻找树的某个节点)
    int NodeLeavesStatistics(int leaves = 0);            //统计叶子数
    int NodeChildrenNodeHeigh();                        //统计子节点的最大高度(包含本节点)/(以本节点作为根求树的高度)
    int NodeChildrenStatistics();                        //统计子节点数(包含本节点)
    int NodeDelete();                                    //删除节点
    //traversal
    void NodePreorderTraversal();
    void NodeInorderTraversal();
    void NodeSubsequentTraversal();

private:
    int m_iIndex;
    T m_tData;
    BiTreeNode *m_pParent;
    BiTreeNode *m_pLeftChild;
    BiTreeNode *m_pRightChild;

    //struct NodeWidth<T> stNodeWidth;
};

template <typename T>
BiTreeNode<T>::BiTreeNode()
{
    m_iIndex = 0;
    m_tData = 0;
    m_pParent = NULL;
    m_pLeftChild = NULL;
    m_pRightChild = NULL;
}

template <typename T>
BiTreeNode<T>::BiTreeNode(int index,T data)
{
    m_iIndex = index;
    m_tData = data;
    m_pParent = NULL;
    m_pLeftChild = NULL;
    m_pRightChild = NULL;
}

template <typename T>
BiTreeNode<T>::~BiTreeNode()
{
    if(m_pLeftChild != NULL)
    {
        m_pLeftChild->NodeDelete();
        m_pLeftChild = NULL;
    }
    if(m_pRightChild != NULL)
    {
        m_pRightChild->NodeDelete();
        m_pRightChild = NULL;
    }
    m_pParent = NULL;
}
/*-----------------------getdata------------------------*/
template <typename T>
int BiTreeNode<T>::getIndex()
{
    return m_iIndex;
}


template <typename T>
T BiTreeNode<T>::getData()
{
    return m_tData;
}

template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getParent()
{
    return m_pParent;
}

template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getLChild()
{
    return m_pLeftChild;
}

template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getRChild()
{
    return m_pRightChild;
}

template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getInorderPrecursor()
{
    /*
        condition 1: Node has left child.
        condition 2: Node hasn't left child,and it is its father right child.
        condition 3: Node hasn't left child,and it is its father left child.
    */
    /*condition 1:node has left child*/
    if(NULL != this->getLChild())
    {
        BiTreeNode *tempNode=this->getLChild();
        while(NULL != tempNode->getRChild() )
        {
            tempNode=tempNode->getRChild();
        }
        return  tempNode;
    }
    else
    {
        BiTreeNode *fatherNode=this->getParent();
        if(NULL == fatherNode)
        {
            return NULL;//it is root.
        }
        /*condition 2*/
        else if(fatherNode->getRChild() == this)
        {
            return fatherNode;
        }
        /*condition*/
        else
        {
            while( fatherNode->getParent()->getRChild() != fatherNode)
            {
                fatherNode =fatherNode ->getParent();
                if(NULL == fatherNode )
                {
                    return NULL;//it is root;
                }
            }
            return fatherNode->getParent();
        }
    }
    return NULL;
}

template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getInorderSubsequence()                //获取中序后继
{
    /*
        condition 1: Node has right child.
        condition 2: Node hasn't right child,and it is its father left child.
        condition 3: Node hasn't right child,and it is its father right child.
    */    
    /*condition 1*/
    if(NULL != this->getRChild())
    {
        BiTreeNode *tempNode = this->getRChild();
        while(NULL != tempNode->getLChild() )
        {
            tempNode=tempNode->getLChild();
        }
        return  tempNode;
    }
    /*condition 2*/
    else
    {
        BiTreeNode *fatherNode=this->getParent();
        if(NULL == fatherNode)//it is root.
        {
            return NULL;
        }
        else if(fatherNode->getLChild() == this)
        {
            return fatherNode;
        }
        else
        {
            while(fatherNode->getParent()->getLChild() !=fatherNode)
            {
                fatherNode=fatherNode->getParent();
                if(NULL == fatherNode)
                {
                    return NULL;//it is root;
                }
            }
            return fatherNode->getParent();
        }
    }
}
/*-----------------------setdata------------------------*/
template <typename T>
void BiTreeNode<T>::setIndex(int index)
{
    m_iIndex = index;
}
template <typename T>
void BiTreeNode<T>::setData(T data)
{
    m_tData = data;
}
template <typename T>
void BiTreeNode<T>::setParenet(BiTreeNode *Node)
{
    m_pParent = Node;
}

template <typename T>
void BiTreeNode<T>::setLChild(BiTreeNode *Node)
{
    m_pLeftChild = Node;
}

template <typename T>
void BiTreeNode<T>::setRChild(BiTreeNode *Node)
{
    m_pRightChild = Node;
}

/*-----------------------else------------------------*/
template <typename T>
BiTreeNode<T> *BiTreeNode<T>::NodeSearch(int index)
{
    BiTreeNode<T> *tempNode = NULL;
    if(m_iIndex == index)
    {
        return this;
    }
    if(m_pLeftChild != NULL)
    {
        tempNode = m_pLeftChild->NodeSearch(index);
        if(tempNode != NULL)//match
        {
            return tempNode;
        }
    }

    if(m_pRightChild !=NULL)
    {
        tempNode = m_pRightChild->NodeSearch(index);
        if(tempNode != NULL)// match
        {
            return tempNode;
        }
    }


    return NULL;
}

/*statistcal children node heigh(includding me)*/
template <typename T>
int BiTreeNode<T>::NodeChildrenNodeHeigh()
{
    int heightLeft =0 ;
    int heightRight =0; 
    if(m_pLeftChild != NULL)
    {
        heightLeft += m_pLeftChild->NodeChildrenNodeHeigh();    
    }
    if(m_pRightChild != NULL)
    {
        heightRight += m_pRightChild->NodeChildrenNodeHeigh();
    }
    if(heightRight > heightLeft)
    {
        return ++heightRight;
    }
    else
    {
        return ++heightLeft;
    }
}

/*statistcal leaves node(includding me)*/
template <typename T>
int BiTreeNode<T>::NodeLeavesStatistics(int leaves)
{
    if(this->m_pLeftChild != NULL)
    {
        leaves = this->m_pLeftChild->NodeLeavesStatistics(leaves);
    }
    if(this->m_pRightChild != NULL)
    {
        leaves = this->m_pRightChild->NodeLeavesStatistics(leaves);
    }
    if(this->getLChild() == NULL && this->getRChild() == NULL)
    {
        leaves ++;
    }
    return leaves;    
}
/*statistcal children node(includding me)*/
template <typename T>
int BiTreeNode<T>::NodeChildrenStatistics()
{
    int iCnt=0;
    if(this->m_pLeftChild != NULL)
    {
        iCnt+=this->m_pLeftChild->NodeChildrenStatistics();
    }
    if(this->m_pRightChild!= NULL)
    {
        iCnt+=this->m_pRightChild->NodeChildrenStatistics();
    }
    iCnt++;
    return iCnt;
}

template <typename T>
int  BiTreeNode<T>::NodeDelete()
{
    int Times=0;
    if(this->m_pLeftChild != NULL)
    {
         //delete this->getLChild();
        Times+=this->m_pLeftChild->NodeDelete();
        this->m_pLeftChild =NULL;
    }
    if(this->m_pRightChild!= NULL)
    {
        //delete this->getRChild();
        Times+=this->m_pRightChild->NodeDelete();
        this->m_pRightChild =NULL;
    }
    Times++;
    delete this;
    return Times;
}
/*-----------------------traversal------------------------*/
template <typename T>
void BiTreeNode<T>::NodePreorderTraversal()
{
    cout<<"Index:"<<this->getIndex()<<";Data:"<<this->getData()<<endl;

    if(this->getLChild() != NULL)
    {
        this->getLChild()->NodePreorderTraversal();
    }

    if(this->getRChild() != NULL)
    {
        this->getRChild()->NodePreorderTraversal();
    }
}

template <typename T>
void BiTreeNode<T>::NodeInorderTraversal()
{
    if(this->getLChild() != NULL)
    {
        this->getLChild()->NodeInorderTraversal();
    }

    cout<<"Index:"<<this->getIndex()<<";Data:"<<this->getData()<<endl;

    if(this->getRChild() != NULL)
    {
        this->getRChild()->NodeInorderTraversal();
    }
}

template <typename T>
void BiTreeNode<T>::NodeSubsequentTraversal()
{
    if(this->getLChild() != NULL)
    {
        this->getLChild()->NodeSubsequentTraversal();
    }

    if(this->getRChild() != NULL)
    {
        this->getRChild()->NodeSubsequentTraversal();
    }

    cout<<"Index:"<<this->getIndex()<<";Data:"<<this->getData()<<endl;
}

#endif
View Code

 

BinaryTree.h

#ifndef _BINARYTREE_H
#define _BINARYTREE_H

#include <iostream>
#include <queue>
#include "BiTreeNode.h"
using namespace std;

template <typename T>
class BinaryTree
{
public:
    BinaryTree(int size,int index,T data);
    BinaryTree(int size);
    virtual ~BinaryTree();
    bool IsTreeEmpty();                                                //树是否为空
    bool IsTreeFull();                                                //树的容量是否已满
    //search    
    BiTreeNode<T> *getNodeByIndex(int index);                        //通过索引搜索节点
    int getLeaves();                                                //获取树的叶子数
    int getHeight();                                                //获取树的高度(包含根节点)
    int getWidth();                                                    //获取树的宽度(包含根节点)
    int getNowSize();                                                //获取树现在的节点数(包含根节点)
    int getMaxSize();                                                //获取树的最大节点数
    //add/delete
    bool addLeftNodeByIndex(int newIndex,T data,int searchIndex);    //添加左子树(使用索引)
    bool addRightNodeByIndex(int newIndex,T data,int searchIndex);  //添加右子树(使用索引)
    bool addLeftNodeByNode(int index,T data,BiTreeNode<T> *pNode);  //添加左子树(使用节点地址)
    bool addRightNodeByNode(int index,T data,BiTreeNode<T> *pNode); //添加右子树(使用节点地址)

    virtual bool deleteNodeByIndex(int index);                        //删除节点(使用索引)
    virtual bool deleteNodeByNode(BiTreeNode<T> *pNode);            //删除节点(使用地址)

    //traversal
    void PreorderTraversal();                                        //先序遍历
    void InorderTraversal();                                        //中序遍历
    void SubsequentTraversal();                                        //后序遍历

protected:
    BiTreeNode<T> *m_pRoot;                                            //tree root
    int m_iSize;                                                    //Tree now nodes size (without root)
    int m_iMaxSize;                                                    //Tree max nodes size (without root) 
};

template <typename T>
BinaryTree<T>::BinaryTree(int size,int index,T data)
{
    m_pRoot = new BiTreeNode<T>(index,data);
    m_pRoot->setLChild(NULL);
    m_pRoot->setRChild(NULL);
    m_pRoot->setParenet(NULL);
    m_iSize = 1;
    m_iMaxSize = size;    
}

template <typename T>
BinaryTree<T>::BinaryTree(int size)
{
    m_pRoot = new BiTreeNode<T>(0,0);
    m_pRoot->setLChild(NULL);
    m_pRoot->setRChild(NULL);
    m_pRoot->setParenet(NULL);
    m_iSize = 1;
    m_iMaxSize = size;
}


template <typename T>
BinaryTree<T>::~BinaryTree()
{
    if(NULL != m_pRoot)
        delete m_pRoot;
    m_pRoot=NULL;
}

template <typename T>
bool BinaryTree<T>::IsTreeEmpty()
{
    if(m_iSize == 0)
        return true;
    return false;    
}

template <typename T>
bool BinaryTree<T>::IsTreeFull()
{
    if(m_iSize >= m_iMaxSize)
        return true;
    return false;
}

//search
template <typename T>
BiTreeNode<T> *BinaryTree<T>::getNodeByIndex(int index)
{
    if(NULL == m_pRoot)
    {
        return NULL;
    }
    return m_pRoot->NodeSearch(index);
}

template <typename T>
int BinaryTree<T>::getLeaves()
{    
    if(NULL == m_pRoot)
    {
        return 0;
    }
    return m_pRoot->NodeLeavesStatistics();
}

template <typename T>
int BinaryTree<T>::getWidth()
{
    if(NULL == m_pRoot)
    {
        return 0;
    }
    int maxWidth=1;                //save max width
    int parentWidth=0;            //save this width
    int childrenWidth=0;        //save next width
    queue<BiTreeNode<T>*> stdQueue;
    BiTreeNode<T> *tempNode = m_pRoot;
    if(tempNode -> getLChild() != NULL)
    {
        stdQueue.push(tempNode -> getLChild());
        parentWidth ++;
    }
    if(tempNode -> getRChild() != NULL)
    {
        stdQueue.push(tempNode ->getRChild());
        parentWidth ++;
    }

    while(!stdQueue.empty())
    {
        while(parentWidth>0)
        {
            tempNode = stdQueue.front();
            stdQueue.pop();
            if(tempNode -> getLChild() != NULL)
            {
                stdQueue.push(tempNode -> getLChild());
                childrenWidth ++;
            }
            if(tempNode -> getRChild() != NULL)
            {
                stdQueue.push(tempNode ->getRChild());
                childrenWidth ++;
            }
            parentWidth --;
        }
        parentWidth = childrenWidth;
        if(parentWidth > maxWidth)
        {
            maxWidth = parentWidth;
        }
        childrenWidth =0;
    }

//    result =  m_pRoot->NodeChildrenNodeWidth(&child);
    return maxWidth;
}


template <typename T>
int BinaryTree<T>::getHeight()
{
    if(NULL == m_pRoot)
        return 0;
    return m_pRoot->NodeChildrenNodeHeigh();//including root 
}

template <typename T>
int BinaryTree<T>::getNowSize()
{
    if(NULL == m_pRoot)
    {
        return 0;
    }
    //return m_iSize;//quickly get Size
    return m_pRoot ->NodeChildrenStatistics();//including root
}

template <typename T>
int BinaryTree<T>::getMaxSize()
{
    return m_iMaxSize ;
}

//add/delete
template <typename T>
bool BinaryTree<T>::addLeftNodeByIndex(int newIndex,T data,int searchIndex)
{
    if(NULL == m_pRoot)
    {
        return false;
    }
    BiTreeNode<T> *tempNode;
    tempNode = m_pRoot->NodeSearch(searchIndex);//find the node that index  is = searchIndex
    if(tempNode!=NULL)
    {
        return addLeftNodeByNode(newIndex,data,tempNode);
    }
    return false;
}
template <typename T>
bool BinaryTree<T>::addRightNodeByIndex(int newIndex,T data,int searchIndex)
{
    if(NULL == m_pRoot)
    {
        return false;
    }
    BiTreeNode<T> *tempNode ;
    tempNode = m_pRoot->NodeSearch(searchIndex);
    if(tempNode!=NULL)
    {
        return addRightNodeByNode(newIndex,data,tempNode);
    }
    return false;
}
template <typename T>
bool BinaryTree<T>::addLeftNodeByNode(int index,T data,BiTreeNode<T> *pNode)
{
    BiTreeNode<T> *pNodeCopy = pNode;//make a copy of pNode to protect the pNode being changed by accidentally
    if(IsTreeFull())
    {
        return false ;
    }
    if(pNodeCopy -> getLChild() == NULL)
    {
        BiTreeNode<T> *newNode = new BiTreeNode<T>(index,data);
        pNodeCopy->setLChild(newNode);
        newNode->setParenet(pNodeCopy);
    }
    else 
    {
        return false ;
    }

    m_iSize++;
    return true;
}

template <typename T>
bool BinaryTree<T>::addRightNodeByNode(int index,T data,BiTreeNode<T> *pNode)
{
    BiTreeNode<T> *pNodeCopy = pNode;//make a copy of pNode to protect the pNode being changed by accidentally
    if(IsTreeFull())
    {
        return false ;
    }
    if(pNodeCopy -> getRChild() == NULL)
    {
        BiTreeNode<T> *newNode = new BiTreeNode<T>(index,data);
        pNodeCopy->setRChild(newNode);
        newNode->setParenet(pNodeCopy);
    }
    else 
    {
        return false ;
    }

    m_iSize++;
    return true;
}


template <typename T>
bool BinaryTree<T>::deleteNodeByIndex(int index)
{
    if(IsTreeEmpty())
    {
        return false;
    }

    BiTreeNode<T> *deleteNode = m_pRoot->NodeSearch(index);
    if(deleteNode != NULL)
    {
        if(deleteNode == m_pRoot)
        {
            cout<<"BinaryTree<T>::deleteNodeByIndex():"<<index<<"是根节点不能删除"<<endl;
            return false;
        }
        return deleteNodeByNode(deleteNode);
    }
    return false;
}
template <typename T>
bool BinaryTree<T>::deleteNodeByNode(BiTreeNode<T> *pNode)
{
    if(IsTreeEmpty())
        return false;

    if(pNode!=NULL)
    {
        /*clear parent Node L/RChild*/ 
        BiTreeNode<T> *parentNode = pNode->getParent();
        if(parentNode != NULL)
        {
            if(parentNode->getLChild() == pNode)
            {
                parentNode->setLChild(NULL);
            }
            else
            {
                parentNode->setRChild(NULL);
            }
        }
        /*delete node*/
        int SizeDec;//use to caculate how much Node was delete
        SizeDec = pNode->NodeDelete();
        m_iSize-=SizeDec;
        return true;
    }
    return false;
}

//traversal
template <typename T>
void BinaryTree<T>::PreorderTraversal()
{
    cout<<"PerorderTraversal:"<<endl;
    if(NULL == m_pRoot)
    {
        return ;
    }
    m_pRoot ->NodePreorderTraversal();
}
template <typename T>
void BinaryTree<T>::InorderTraversal()
{
    cout<<"InorderTraversal:"<<endl;
    if(NULL == m_pRoot)
    {
        return ;
    }
    m_pRoot ->NodeInorderTraversal();
}
template <typename T>
void BinaryTree<T>::SubsequentTraversal()
{
    cout<<"SubsequentTraversal:"<<endl;
    if(NULL == m_pRoot)
    {
        return ;
    }
    m_pRoot ->NodeSubsequentTraversal();
}

#endif 
View Code

 

main.c(本部分用于测试)

#include <iostream>
#include <vector>
#include "BinaryTree.h"
#include "BinarySearchTree.h"

using namespace std;


int main()
{
    BinaryTree<int> *tree = new BinaryTree<int>(20,1,10);
    tree->addLeftNodeByIndex(2,9,1);
    tree->addRightNodeByIndex(3,6,1);
    tree->addLeftNodeByIndex(4,8,2);
    tree->addRightNodeByIndex(5,7,2);
    tree->addLeftNodeByIndex(6,5,3);
    tree->addRightNodeByIndex(7,4,3);
    //preorderTraversal()/InorderTraversal()/SubsequentTraversal() check
    tree->PreorderTraversal();
    //tree->InorderTraversal();
    //tree->SubsequentTraversal();

    //getNowSize() check
    cout<<"tree size(except root):"<<tree->getNowSize()<<endl;

    //getLeaves() check;
    cout<<"tree leaves:"<<tree->getLeaves()<<endl;

    //getHeight() check;
    cout<<"getHeight():"<<tree->getHeight()<<endl;

    //getWidth() check;
    cout<<"getWidth():"<<tree->getWidth()<<endl;

    //deleteNodeByIndex() check
    tree->deleteNodeByIndex(2);
    tree->PreorderTraversal();


    system("pause");
    return 0;
}
View Code

 

测试结果:

 

程序详解

以下介绍几点

  1. 树的基本结构
  2. 构建树
  3. 添加左/右节点
  4. 统计叶子
  5. 统计高度
  6. 统计宽度

 

一、数的基本结构

  树由两部分构成,结点类(BiTreeNode.h)和树的本体(BinaryTree.h)

  节点类中的内容用于储存数据,树的本体中将这些节点连接起来。

  节点的主要成员:

  1.   节点索引号m_iIndex:用于标记节点号码,如图红色的数字
  2.   节点数据m_tData: 用于标记节点数字,如图黑色数字
  3.   节点的父节点指针*m_pParent:通过该指针可以找到在树中该节点的父亲
  4.   节点的左子节点指针*m_pLeftChild:通过该指针可以找到在树中该节点的左孩子
  5.   节点的右子节点指针*m_pRightChild:通过该指针可以找到树中该节点的右孩子
private:
    int m_iIndex;
    T m_tData;
    BiTreeNode *m_pParent;
    BiTreeNode *m_pLeftChild;
    BiTreeNode *m_pRightChild;

  二叉树的主要成员:

  1.   树根指针*m_pRoot:该指针指向树的根节点
  2.   树的现有节点数m_iSize:指示现在树的节点
  3.   树的最大节点树m_iMaxSize:指示这棵树最大可以存放多少节点
protected:
    BiTreeNode<T> *m_pRoot;                                            //tree root
    int m_iSize;                                                    //Tree now nodes size (without root)
    int m_iMaxSize;    

 

二、构建树:BinaryTree构造函数

  1. 创建根节点
  2. 设置根节点的父母和左右孩子为空
  3. 设置树的大小为1,最大节点数为size。
template <typename T>
BinaryTree<T>::BinaryTree(int size,int index,T data)
{
    m_pRoot = new BiTreeNode<T>(index,data);
    m_pRoot->setLChild(NULL);
    m_pRoot->setRChild(NULL);
    m_pRoot->setParenet(NULL);
    m_iSize = 1;
    m_iMaxSize = size;    
}

 

三、添加左(右)节点addLeftNodeByNode()/addLeftNodeByIndex()

方法一、在目标节点后面添加新节点addLeftNodeByNode()

  1. 树没有空间则不能添加,返回失败。
  2. 如果目标节点的左子为空,使用(index,data)创建一个新的节点,并把该节点挂在目标节点后
template <typename T>
bool BinaryTree<T>::addLeftNodeByNode(int index,T data,BiTreeNode<T> *pNode)
{
    BiTreeNode<T> *pNodeCopy = pNode;//make a copy of pNode to protect the pNode being changed by accidentally
    if(IsTreeFull())
    {
        return false ;
    }
    if(pNodeCopy -> getLChild() == NULL)
    {
        BiTreeNode<T> *newNode = new BiTreeNode<T>(index,data);
        pNodeCopy->setLChild(newNode);
        newNode->setParenet(pNodeCopy);
    }
    else 
    {
        return false ;
    }

    m_iSize++;
    return true;
}

方法二、通过索引添加新节点addLeftNodeByIndex()

  1. 使用节点中Node_Search()方法从根节点开始查找索引为searchIndex的节点,找到并取出目标节点的指针
  2. 使用方法一为目标节点添加左节点
template <typename T>
bool BinaryTree<T>::addLeftNodeByIndex(int newIndex,T data,int searchIndex)
{
    if(NULL == m_pRoot)
    {
        return false;
    }
    BiTreeNode<T> *tempNode;
    tempNode = m_pRoot->NodeSearch(searchIndex);//find the node that index  is = searchIndex
    if(tempNode!=NULL)
    {
        return addLeftNodeByNode(newIndex,data,tempNode);
    }
    return false;
}

 

四、统计叶子

从树根开始往下搜索,如果一个节点的没有左右子节点,那么它为叶子。在节点类中递归实现

template <typename T>
int BinaryTree<T>::getLeaves()
{    
    if(NULL == m_pRoot)
    {
        return 0;
    }
    return m_pRoot->NodeLeavesStatistics();
}
template <typename T>
int BiTreeNode<T>::NodeLeavesStatistics(int leaves)
{
    if(this->m_pLeftChild != NULL)
    {
        leaves = this->m_pLeftChild->NodeLeavesStatistics(leaves);
    }
    if(this->m_pRightChild != NULL)
    {
        leaves = this->m_pRightChild->NodeLeavesStatistics(leaves);
    }
    if(this->getLChild() == NULL && this->getRChild() == NULL)
    {
        leaves ++;
    }
    return leaves;    
}

 

五、统计高度

 从树根开始一直往下搜索。直到找到了叶子(无左右孩子)。在节点类中递归实现

template <typename T>
int BinaryTree<T>::getHeight()
{
    if(NULL == m_pRoot)
        return 0;
    return m_pRoot->NodeChildrenNodeHeigh();//including root 
}
template <typename T>
int BiTreeNode<T>::NodeChildrenNodeHeigh()
{
    int heightLeft =0 ;
    int heightRight =0; 
    if(m_pLeftChild != NULL)
    {
        heightLeft += m_pLeftChild->NodeChildrenNodeHeigh();    
    }
    if(m_pRightChild != NULL)
    {
        heightRight += m_pRightChild->NodeChildrenNodeHeigh();
    }
    if(heightRight > heightLeft)
    {
        return ++heightRight;
    }
    else
    {
        return ++heightLeft;
    }
}

 

六、统计宽度

如图所示,这棵树第一层宽度为1,第二层宽度为2,第三层宽度为4,所以这棵树的最大宽度为4

综上所述我们需要统计最节点数最多的一层有几个节点,所以我们按层统计

  1. 创建一个队列stdQueue存放节点,一个parentWidth用于储存上一层的宽度,一个childrenWidth用于储存下一层的宽度,以及一个maxWidth用于储存出现过的最大宽度。
  2. 把根节点的两个孩子(黑色9和黑色6)加入队列中,每加一个parentWidth+1,这时队列中有两个元素,parentWidth等于2。此时队列中有两个元素(6,8),parentWidth=2;childrenWidth=0;maxWidth=2
  3. 从队列中取出第一个元素(9),parentWidth-1,此时parentWidth=1,他有两个孩子(黑色8黑色7)加入队列中,childrenWidth+=2。此时队列中有三个元素(6,8,7),parentWidth=1;childrenWidth=2
  4. 同上,从队列中取出第一个元素(6),parentWidth-1,此时parentWidth=0,他的两个孩子(黑5和黑4)加入队列中,childrenWidth+=2。此时队列中有四个元素(8,7,5,4),parentWidth=0;childrenWidth=4
  5. 由于parentWidth=0了,所以本层统计完成,让parentWidth=childrenWidth开始统计下一层。此时队列中有四个元素(8,7,5,4),parentWidth=4;childrenWidth=0;maxWidth=4;
  6. 同第3、4步,取出队列中第一个元素(8),它没有孩子,取出队列中第二个元素(7),它没有孩子...直到队列元素取出完毕,因为他们都没有子节点,所以队列为空,就是统计完成的条件。maxWidth=4;

 

template <typename T>
int BinaryTree<T>::getWidth()
{
    if(NULL == m_pRoot)
    {
        return 0;
    }
    int maxWidth=1;                //save max width
    int parentWidth=0;            //save this width
    int childrenWidth=0;        //save next width
    queue<BiTreeNode<T>*> stdQueue;
    BiTreeNode<T> *tempNode = m_pRoot;
    if(tempNode -> getLChild() != NULL)
    {
        stdQueue.push(tempNode -> getLChild());
        parentWidth ++;
    }
    if(tempNode -> getRChild() != NULL)
    {
        stdQueue.push(tempNode ->getRChild());
        parentWidth ++;
    }

    while(!stdQueue.empty())
    {
        while(parentWidth>0)
        {
            tempNode = stdQueue.front();
            stdQueue.pop();
            if(tempNode -> getLChild() != NULL)
            {
                stdQueue.push(tempNode -> getLChild());
                childrenWidth ++;
            }
            if(tempNode -> getRChild() != NULL)
            {
                stdQueue.push(tempNode ->getRChild());
                childrenWidth ++;
            }
            parentWidth --;
        }
        parentWidth = childrenWidth;
        if(parentWidth > maxWidth)
        {
            maxWidth = parentWidth;
        }
        childrenWidth =0;
    }

//    result =  m_pRoot->NodeChildrenNodeWidth(&child);
    return maxWidth;
}

 

posted @ 2017-07-24 22:16  HongYi_Liang  阅读(1722)  评论(0编辑  收藏  举报