补空法:若子树为空则使用#来补
o A
/ \
B o o C
/ \ / \
D o Eo oF #
/\ /\ /\
# ## ## o G
/ \
# #
输入ABCDEFG,转换为二叉树
前序遍历:
ABDECFG
考虑#的前序遍历:
ABD##E##CF#G###
将考虑#的前序遍历的结果转换为二叉树:
o A
B o
D o Eo
o A
B o
D o Eo
/\
# #
o A
B o
/
D o Eo
/\ /\
# ## #
o A
/
B o
/ \
D o Eo
/\ /\
# ## #
o A
/
B o o C
/ \
D o Eo oF
/\ /\ /\
# ## ## o G
o A
/
B o o C
/ \
D o Eo oF
/\ /\ /\
# ## ## o G
/ \
# #
o A
/
B o o C
/ \ /
D o Eo oF
/\ /\ /\
# ## ## o G
/ \
# #
o A
/
B o o C
/ \ / \
D o Eo oF #
/\ /\ /\
# ## ## o G
/ \
# #
#include <iostream>
#include "fill_blank_bintree.h"
using namespace std;
int main(void)
{
// 返回二叉树指针
struct BinTree_node* mytree;
cout << "请输入以前序遍历并补空后的二叉树,如ABD##E##CF#G###:";
mytree = create_bintree();
cout << "先序遍历结果:";
pre_order(mytree);
cout << endl;
cout << "中序遍历结果:";
mid_order(mytree);
cout << endl;
cout << "后序遍历结果:";
back_order(mytree);
cout << endl;
cout << "层序遍历结果:";
level_traverse(mytree);
cout << endl;
cout << "二叉树的深度 = " << depth(mytree) << endl;
cout << "二叉树叶子的个数 = " << leaf_num(mytree) << endl;
cout << "全部节点个数 = " << node_num(mytree) << endl;
delete mytree;
return 0;
}
fill_blank_bintree.cpp
#include <iostream>
#include "fill_blank_bintree.h"
#include "queue.h"
using namespace std;
struct BinTree_node* create_bintree()
{
char ch;
struct BinTree_node* tree;
// 把输入的第一个字母放到ch
cin >> ch;
if(ch == '#')
// 指针指向空
tree = nullptr;
else
{
// 指针指向开辟好的空间
tree = new BinTree_node();
// tree = (struct BinTree_node*)malloc(sizeof(struct BinTree_node));
// 先访问根节点
tree->elem = ch;
tree->Ltree = create_bintree();
tree->Rtree = create_bintree();
}
return tree;
}
// 前序遍历
void pre_order(struct BinTree_node* tree)
{
// 如果存在根节点
if(tree)
{
// 1.先访问根节点
cout << tree->elem << " ";
// 2.访问左子树的根节点,3.直到左子树没有后续节点(递归调用)
pre_order(tree->Ltree);
// 4.左子树访问完,相同方法访问右子树
pre_order(tree->Rtree);
}
}
// 中序遍历
void mid_order(struct BinTree_node* tree)
{
// 如果存在根节点
if(tree)
{
// 1.先找左子树,发现它还能分成左子树
mid_order(tree->Ltree);
// 2.访问没有没有左子树的节点,3.访问根节点,再访问右子树
cout << tree->elem << " ";
// 4.左子树访问完,相同方法访问右子树
mid_order(tree->Rtree);
}
}
// 后序遍历
void back_order(struct BinTree_node* tree)
{
// 如果存在根节点
if(tree)
{
// 1.先找左子树,发现它还能分成左子树
back_order(tree->Ltree);
// 2.访问没有没有左子树的节点,3.访问根节点,再访问右子树
// 4.左子树访问完,相同方法访问右子树
back_order(tree->Rtree);
cout << tree->elem << " ";
}
}
void level_traverse(struct BinTree_node* tree)
{
// 1.创建队列,让根节点A先进入队列
enqueue(*tree);
// 结构体对象
struct BinTree_node node;
// 若队列不空
while(!isempty())
{
// 队列的头出队列,「同时」队列头的左子树和右子树入队列
node = dequeue();
// 打印,表示访问过
cout << node.elem << " ";
// 若当前节点有左子树,同时队列头的左子树和右子树入队列
if(node.Ltree)
enqueue(*node.Ltree);
if(node.Rtree)
enqueue(*node.Rtree);
}
}
unsigned int depth(struct BinTree_node* tree)
{
unsigned int L_depth = 0;
unsigned int R_depth = 0;
// 二叉树为空:到达叶子节点
if(tree == nullptr)
return 0;
else// 二叉树的深度 = 左右子树最大深度加1
{
// 条件表达式返回的值赋值
// 返回左子树深度:2
L_depth = depth(tree->Ltree);
// 返回右子树深度:3
R_depth = depth(tree->Rtree);
// 条件表达式:如果左边的深度大于右边的深度,则左边的深度+1,否则右边的深度+1
return (L_depth > R_depth) ? (L_depth + 1) : (R_depth + 1);// 3>2
}
}
/*
叶子节点个数
不再继续分左右子树的节点:DEG
o A →
/ \
B o o C →
/ \ /
D o Eo oF →
\
o G →
*/
unsigned int leaf_num(struct BinTree_node* tree)
{
// 情况1.二叉树为空,叶子节点个数 == 0
if(tree == NULL)
return 0;
// 情况2.只有根节点,无左右子树,叶子节点个数 == 1
else if(tree->Ltree == NULL && tree->Rtree == NULL)
return 1;
else
// 情况3.整个二叉树的叶子节点个数 == 左子树的叶子个数 + 右子树的叶子个数
return leaf_num(tree->Ltree) + leaf_num(tree->Rtree);// 2 + 1 = 3
}
unsigned int node_num(struct BinTree_node *tree)
{
if(tree == nullptr)
return 0;
else
// 左子树节点个数+右子树节点个数+根节点
return node_num(tree->Ltree) + node_num(tree->Rtree) + 1;
}
fill_blank_bintree.h
#ifndef __GOTHROUGH_BINARY_TREE_H__
#define __GOTHROUGH_BINARY_TREE_H__
struct BinTree_node
{
// 节点内容
unsigned char elem;
// 左子树
struct BinTree_node* Ltree;
// 右子树
struct BinTree_node* Rtree;
};
struct BinTree_node* create_bintree();
void pre_order(struct BinTree_node* tree);
void level_traverse(struct BinTree_node* tree);
void mid_order(struct BinTree_node* tree);
void back_order(struct BinTree_node* tree);
unsigned int depth(struct BinTree_node* tree);
unsigned int leaf_num(struct BinTree_node* tree);
unsigned int node_num(struct BinTree_node *tree);
#endif