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

先来看看它的结构

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

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 = ;
int heightRight =;
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=;
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);
}

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

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=;
tree->pRoot = (BiTreeNode *)malloc(sizeof(BiTreeNode));
BiTreeNode_Reset(tree->pRoot,,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,);
} /*******************************************************/
/*******************************************************/
/**********************高度统计*************************/
/*******************************************************/
/*******************************************************/
int getHeight(BinaryTree *tree)
{
return NodeChildrenNodeHeigh(tree->pRoot);
}
/*******************************************************/
/*******************************************************/
/**********************宽度统计*************************/
/*******************************************************/
/*******************************************************/
int getWidth(BinaryTree *tree)
{
int maxWidth=; //save max width
int parentWidth=; //save this width
int childrenWidth=; //save next width
BiTreeNode *tempNode = tree->pRoot;
Queue *myQueue = (Queue*)malloc(sizeof(Queue)); //create queue
Queue_Create(myQueue,); 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>)
{
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 =;
} 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);
}

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

其他需要使用的关联文件

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 = ;
queue->iTail=;
queue->iHead=;
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 == )
{
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 ;
} queue->Datas[queue->iTail] = data;
QueueTailAdd(queue);
queue->iLength++;
return true;
}
/*******************************************************/
/*******************************************************/
/************获取队头第一个元素(不删除)***************/
/*******************************************************/
/*******************************************************/
ElemQueue Queue_front(Queue *queue)
{
if(isQueueEmpty(queue))
{
return ;
} return queue->Datas[queue->iHead];
}
ElemQueue Queue_back(Queue *queue)
{
if(isQueueEmpty (queue))
{
return ;
}
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=;i<queue->iLength;i++)
{
printf("%d ",queue->Datas[temp++%queue->iSize]);
} }

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

Mystdbool.h(用于声明bool)

#ifndef __MYSTDBOOL_H
#define __MYSTDBOOL_H typedef enum Bool
{
false=,
true,
}bool; #endif

main.c(用于测试)

#include <stdlib.h>
#include <stdio.h>
#include "BinaryTree.h" int main(void)
{
BinaryTree tree={};
BinaryTreeCreate(&tree,,);
//first level
addLeftNodeByIndex(&tree,,,);
addRightNodeByIndex(&tree,,,);
//second level
addLeftNodeByIndex(&tree,,,);
addRightNodeByIndex(&tree,,,);
addLeftNodeByIndex(&tree,,,);
addRightNodeByIndex(&tree,,,); 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 ;
}

运行结果:





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 = ); //统计叶子数
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 = ;
m_tData = ;
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 = ;
int heightRight =;
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=;
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=;
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

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 = ;
m_iMaxSize = size;
} template <typename T>
BinaryTree<T>::BinaryTree(int size)
{
m_pRoot = new BiTreeNode<T>(,);
m_pRoot->setLChild(NULL);
m_pRoot->setRChild(NULL);
m_pRoot->setParenet(NULL);
m_iSize = ;
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 == )
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 ;
}
return m_pRoot->NodeLeavesStatistics();
} template <typename T>
int BinaryTree<T>::getWidth()
{
if(NULL == m_pRoot)
{
return ;
}
int maxWidth=; //save max width
int parentWidth=; //save this width
int childrenWidth=; //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>)
{
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 =;
} // result = m_pRoot->NodeChildrenNodeWidth(&child);
return maxWidth;
} template <typename T>
int BinaryTree<T>::getHeight()
{
if(NULL == m_pRoot)
return ;
return m_pRoot->NodeChildrenNodeHeigh();//including root
} template <typename T>
int BinaryTree<T>::getNowSize()
{
if(NULL == m_pRoot)
{
return ;
}
//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

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

#include <iostream>
#include <vector>
#include "BinaryTree.h"
#include "BinarySearchTree.h" using namespace std; int main()
{
BinaryTree<int> *tree = new BinaryTree<int>(,,);
tree->addLeftNodeByIndex(,,);
tree->addRightNodeByIndex(,,);
tree->addLeftNodeByIndex(,,);
tree->addRightNodeByIndex(,,);
tree->addLeftNodeByIndex(,,);
tree->addRightNodeByIndex(,,);
//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();
tree->PreorderTraversal(); system("pause");
return ;
}

测试结果:

程序详解

以下介绍几点

  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 = ;
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 ;
}
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 ;
return m_pRoot->NodeChildrenNodeHeigh();//including root
}
template <typename T>
int BiTreeNode<T>::NodeChildrenNodeHeigh()
{
int heightLeft = ;
int heightRight =;
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 ;
}
int maxWidth=; //save max width
int parentWidth=; //save this width
int childrenWidth=; //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>)
{
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 =;
} // result = m_pRoot->NodeChildrenNodeWidth(&child);
return maxWidth;
}

数据结构-二叉树 C和C++实现的更多相关文章

  1. 什么是泛型?,Set集合,TreeSet集合自然排序和比较器排序,数据结构-二叉树,数据结构-平衡二叉树

    ==知识点== 1.泛型 2.Set集合 3.TreeSet 4.数据结构-二叉树 5.数据结构-平衡二叉树 ==用到的单词== 1.element[ˈelɪmənt] 要素 元素(软) 2.key[ ...

  2. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  3. 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java

    前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ...

  4. 数据结构——二叉树(Binary Trees)

    非线性数据结构 二叉搜索树(Binary Search Tree) 树的密度=结点数/高度 二叉树类 #pragma once class stnode { public: int nodeValue ...

  5. [ An Ac a Day ^_^ ] hdu 1662 Trees on the level 数据结构 二叉树

    紫书上的原题 正好学数据结构拿出来做一下 不知道为什么bfs的队列一定要数组模拟…… 还可以练习一下sscanf…… #include<stdio.h> #include<iostr ...

  6. 数据结构二叉树的所有基本功能实现。(C++版)

    本人刚学数据结构,对树的基本功能网上找不到C++代码 便自己写了一份,贴出方便大家进行测试和学习. 大部分功能未测试,如有错误或者BUG,请高手们指教一下,谢谢. 结点声明: BinTreeNode. ...

  7. python实战--数据结构二叉树

    此文将讲述如何用python实战解决二叉树实验 前面已经讲述了python语言的基本用法,现在让我们实战一下具体明确python的用法 点击我进入python速成笔记 先看一下最终效果图: 首先我们要 ...

  8. FBI树-数据结构(二叉树)

    问题 B: [2004_p4]FBI树-数据结构 时间限制: 1 Sec  内存限制: 125 MB提交: 57  解决: 46 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称 ...

  9. (2)Java数据结构--二叉树 -和排序算法实现

    === 注释:此人博客对很多个数据结构类都有讲解-并加以实例 Java API —— ArrayList类 & Vector类 & LinkList类Java API —— BigDe ...

  10. Python数据结构——二叉树

    数的特征和定义: 树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构,很象自然界中的树那样.树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都 ...

随机推荐

  1. C++学习(五)入门篇——基本类型

    面向对象编程的本质是设计并扩展自己的数据类型,让类型和数据匹配. 内置C++分成两种类型:基本类型和复合类型 1.简单变量 程序需要存储信息时,必须记录三个基本属性 (1)信息将存储在哪 (2)要存储 ...

  2. 浅谈JVM与内存分配

    一.程序内存分配 初始内存分配 当一个程序准备运行时,它首先向java虚拟机要内存,但是java虚拟机本身没有权限,它只能向操作系统申请内存,此时java虚拟机会拥有一个初始内存, 此处额外说明一下e ...

  3. 有关struts中DispatchAction的用法小结

       今天刚刚看了DispatchAction觉得这个东西有点意思,所以就写点东西,通过它的名字我想应该可以明白它的作用了,用于分发的Action,主要的好处是把一些功能类似的Action放到一个Ac ...

  4. 初学 Python(十二)——高阶函数

    初学 Python(十二)--高阶函数 初学 Python,主要整理一些学习到的知识点,这次是高阶函数. #-*- coding:utf-8 -*- ''''' 话说高阶函数: 能用函数作为参数的函数 ...

  5. Android异步处理技术

    前言: 在移动端开发中,我们必须正确处理好主线程和子线程之间的关系,耗时操作必须在子线程中完成,避免阻塞主线程,导致ANR.异步处理技术是提高引用性能,解决主线程和子线程之间通信问题的关键. 通常在如 ...

  6. Redux源码分析之compose

    Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...

  7. POJ 2386 Lake Counting (简单深搜)

    Description Due to recent rains, water has pooled in various places in Farmer John's field, which is ...

  8. Git版本控制系统之基本使用

    最早是通过接触著名的开源社区Github了解到Git的,但一直没有系统学习过.这次下定决心从头到尾系统的学一学,也将学习过程记录于此,供大家批驳.本篇文章先从以下几个方面简单了解一下Git: Git的 ...

  9. HttpRequest 类

    关于此类的介绍:查看HttpRequest类 点击查看:HttpRequest中方法的封装 跟这个类对应的HttpResponse类 定义:使 ASP.NET 能够读取客户端在 Web 请求期间发送的 ...

  10. kickstart自动化安装--tftp+nfs+dhcp

    使用kickstart实现Centos 自动化安装 Kickstart自动化安装简介: 规模化:同时装配多台 服务器 自动化 :安装系统,配置各种服务 远程实现:不需要光盘,U盘等安装介质 优势: ( ...