二叉树的概念:
二叉树是度不大于2的有序树,二叉树的每个结点最多有两个子树,分别称为“左子树”和“右子树”。二叉树还常被用于实现二叉查找树和二叉堆。
二叉树的性质:
1.
在二叉树的第
i
层上最多有
2
i-1
个结点(
i ≥ 1
)
2. 深度为d的二叉树最多有2^d-1个结点(d ≥ 1)
3. 对于任意一个二叉树,如果度为0的结点个数为n个,度为2的结点为m个,则n = m + 1。
4. 含n个结点的完全二叉树深度为⌊log2n⌋ +1 。
5. 若对含 n 个结点的完全二叉树从上到下且从左至右进行1至n的编号,则对完全二叉树中编号为i的结点:
(1) 若i=1,则该结点是二叉树的根,无双亲,否则,编号为 ⌊i/2⌋ 的结点为其双亲结点;
(2) 若2i>n,则该结点无左孩子,否则,编号为2i 的结点为其左孩子结点;
(3) 若2i+1>n,则该结点无右孩子,否则,编号为2i+1 的结点为其右孩子结点。
(1) 若i=1,则该结点是二叉树的根,无双亲,否则,编号为 ⌊i/2⌋ 的结点为其双亲结点;
(2) 若2i>n,则该结点无左孩子,否则,编号为2i 的结点为其左孩子结点;
(3) 若2i+1>n,则该结点无右孩子,否则,编号为2i+1 的结点为其右孩子结点。
二叉树的二叉链表存储结构的定义及基本操作的实现:
//库函数头文件包含
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <queue>
using namespace std;
//函数状态码的定义
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int TElemType;
//--------二叉树二叉链表存储表示---------------
typedef struct BiTNode{
TElemType data; //数据域
struct BiTNode *lchild; //左孩子指针域
struct BiTNode *rchild; //右孩子指针域
}BiTNode, *BiTree;
//---------基本操作函数的简单实现---------------
//构造空的二叉树T
Status InitBiTree(BiTree &T){
T = NULL; //直接将根结点赋值为NULL即表示为空树
return OK;
}
//销毁二叉树T
Status DestroyBiTree(BiTree &T){
/*如果树为空,则直接返回OK, 否则,先递归释放左子树,再递归释放右子树,最后释放根结点*/
if(!T)
return OK;
else{
DestroyBiTree(T->lchild);
DestroyBiTree(T->rchild);
free(T);
T = NULL;
return OK;
}
}
//先序构造二叉树T
Status CreateBiTree(BiTree &T){
/*若输入为0,则创建一个空树,否则创建根结点,递归创建左子树,递归创建右子树。*/
TElemType e;
scanf("%d", &e);
if(e == 0)
T = NULL;
else{
T = (BiTNode *)malloc(sizeof(BiTNode));
if(!T)
exit(OVERFLOW);
T->data = e;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
return OK;
}
//判断树是否为空
bool BiTreeEmpty(BiTree T){
if(T == NULL) //根结点为空时表示树为空,返回true,否则返回false
return true;
return false;
}
//返回树的深度
int BiTreeDepth(BiTree T){
int depth = 0;
int depthl, depthr;
if(!T)
depth = 0;
else{
depthl = BiTreeDepth(T->lchild);
depthr = BiTreeDepth(T->rchild);
if(depthl > depthr)
depth = depthl + 1;
else
depth = depthr + 1;
}
return depth;
}
//求二叉树叶子结点的个数
int LeafCount(BiTree T){
if(!T)
return 0;
else if(!T->lchild && !T->rchild)
return 1;
else
return LeafCount(T->lchild) + LeafCount(T->rchild);
}
//统计所有结点数
int NodeCount(BiTree T){
if(!T)
return 0;
else
return 1 + NodeCount(T->lchild) + NodeCount(T->rchild);
}
//visit()函数
Status Print(TElemType e){
printf(" %d", e);
}
//中遍历二叉树
Status InorderTraversal(BiTree T, Status (*visit)(TElemType)){
/*若树空则误操作,若树不空,则先递归地中序遍历左子树,后访问根结点,再递归地中序遍历右子树*/
if(!T)
return OK;
else{
InorderTraversal(T->lchild, visit);
visit(T->data);
InorderTraversal(T->rchild, visit);
}
}
//先序遍历二叉树
Status PreorderTraversal(BiTree T, Status (*visit)(TElemType)){
/*树空无操作,若树不空,则先访问根结点,后递归地先序遍历左子树,再递归地先序遍历右子树 */
if(!T)
return OK;
else{
visit(T->data);
PreorderTraversal(T->lchild, visit);
PreorderTraversal(T->rchild, visit);
}
}
//后序遍历二叉树
Status PostorderTraversal(BiTree T, Status (*visit)(TElemType)){
/*若树空无操作,若树不空,则先递归地后序遍历左子树,后递归地后序遍历,再访问根结点*/
if(!T)
return OK;
else{
PostorderTraversal(T->lchild, visit);
PostorderTraversal(T->rchild, visit);
visit(T->data);
}
}
//层序遍历二叉树
Status LevelorderTraversal(BiTree T, Status (*visit)(TElemType)){
/*如果树空,则不做任何操作,否则,利用队列,将每个结点的左右孩子入队,由于队列的性质,可按层序遍历二叉树*/
if(!T){
printf(" This binary tree is empty!");
return OK;
}
queue<BiTNode*> TreeQueue;
BiTree p = T;
TreeQueue.push(p);
while(!TreeQueue.empty()){
p = TreeQueue.front();
visit(p->data);
if(p->lchild)
TreeQueue.push(p->lchild);
if(p->rchild)
TreeQueue.push(p->rchild);
TreeQueue.pop();
}
return OK;
}
//主函数
int main(){
BiTree T;
InitBiTree(T);
CreateBiTree(T);
printf("The number of nodes in this binary tree is: %d\n", NodeCount(T));
printf("The inorder traversal sequence of the binary tree is:");
InorderTraversal(T, Print);
printf("\nThe preorder traversal sequence of the binary tree is:");
PreorderTraversal(T, Print);
printf("\nThe postorder traversal sequence of the binary tree is:");
PostorderTraversal(T, Print);
printf("\nThe levelorder traversal sequence of the binary tree is:");
LevelorderTraversal(T, Print);
printf("\nThe number of leaves in this binary tree is: %d", LeafCount(T));
printf("\nThe depth of this binary tree is: %d", BiTreeDepth(T));
printf("\nIs the binary empty? ");
if(BiTreeEmpty(T))
printf("YES\n");
else
printf("NO\n");
DestroyBiTree(T);
return 0;
}
下面是对代码的简单测试结果:
输入的二叉树为下图:
运行结果如下图: