目录
一、定义和头文件
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType _data;
struct BinaryTreeNode* _left;
struct BinaryTreeNode* _right;
BinaryTreeNode(const BTDataType& data)
:_data(data),
_left(nullptr),
_right(nullptr)
{}
~BinaryTreeNode()
{
_left = _right = nullptr;
}
}BTNode;
// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi);
// 二叉树销毁
void BinaryTreeDestory(BTNode** root);
// 二叉树节点个数
int BinaryTreeSize(BTNode* root);
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
// 二叉树前序遍历
void BinaryTreePrevOrder(BTNode* root);
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root);
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root);
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root);
// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root);
二、功能实现
#include<iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType _data;
struct BinaryTreeNode* _left;
struct BinaryTreeNode* _right;
BinaryTreeNode(const BTDataType& data)
:_data(data),
_left(nullptr),
_right(nullptr)
{}
~BinaryTreeNode()
{
_left = _right = nullptr;
}
}BTNode;
// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
/*
a : 前序遍历得到二叉树的源string
n : 遍历的长度
pi: 记录当前遍历的下标位置
*/
BTNode* BinaryTreeCreate(const BTDataType* a, int n, int* pi)
{
if (a[*pi] == '#' || *pi > n)
{
(*pi)++;
return nullptr;
}
BTNode* cur = new BTNode(a[(*pi)++]);
cur->_left = BinaryTreeCreate(a, n, pi);
cur->_right = BinaryTreeCreate(a, n, pi);
return cur;
}
// 二叉树销毁
void BinaryTreeDestory(BTNode* root)
{
if (root == nullptr)
return;
BinaryTreeDestory(root->_left);
BinaryTreeDestory(root->_right);
delete root;
}
//int _dfs(BTNode* root, int n)
//{
// if (root == nullptr)
// return n;
//
// n++;
// n = _dfs(root->_left, n);
// n = _dfs(root->_right, n);
// return n;
//}
二叉树节点个数
//int BinaryTreeSize(BTNode* root)
//{
// return _dfs(root, 0);
//}
// 二叉树节点个数
int BinaryTreeSize(BTNode* root)
{
if (!root)
return 0;
return BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right) + 1;
}
//int __dfs(BTNode* root, int n)
//{
// if (root == nullptr)
// return n;
//
// if (!root->_left && !root->_right)
// n++;
// n = __dfs(root->_left, n);
// n = __dfs(root->_right, n);
// return n;
//}
二叉树叶子节点个数
//int BinaryTreeLeafSize(BTNode* root)
//{
// return __dfs(root, 0);
//}
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{
if (!root)
return 0;
else if (!root->_left && !root->_right)
return 1;
return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
// 不断向下寻找 直到第k层 然后分类返回
// 如果是空返回0 反之节点存在 返回1
if (!root)
return 0;
else if (k == 1)
return 1;
return BinaryTreeLevelKSize(root->_left, k - 1) + BinaryTreeLevelKSize(root->_right, k - 1);
}
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
if (!root)
return nullptr;
else if (root->_data == x)
return root;
BinaryTreeFind(root->_left, x);
BinaryTreeFind(root->_right, x);
}
// 二叉树前序遍历
void BinaryTreePrevOrder(BTNode* root)
{
if (!root)
return;
cout << root->_data << ' ';
BinaryTreePrevOrder(root->_left);
BinaryTreePrevOrder(root->_right);
}
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
if (!root)
return;
BinaryTreeInOrder(root->_left);
cout << root->_data << ' ';
BinaryTreeInOrder(root->_right);
}
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
if (!root)
return;
BinaryTreePostOrder(root->_left);
BinaryTreePostOrder(root->_right);
cout << root->_data << ' ';
}
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root)
{
// 层序遍历:利用队列先进先出的性质 每一次出队列都带上下一层的左右节点即可
queue<BTNode*> q;
if (root)
q.push(root);
while (!q.empty())
{
BTNode* front = q.front();
cout << front->_data << ' ';
q.pop();
if (front->_left)
q.push(front->_left);
if (front->_right)
q.push(front->_right);
}
cout << endl;
}
// 判断二叉树是否是完全二叉树
// 完全二叉树是由满二叉树而引出来的
// 若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数(即1~h-1层为一个满二叉树)
// 第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
int BinaryTreeComplete(BTNode* root)
{
// 层序遍历:利用队列先进先出的性质 每一次出队列都带上下一层的左右节点即可
queue<BTNode*> q;
if (root)
q.push(root);
bool flag = false;
while (!q.empty())
{
BTNode* front = q.front();
q.pop();
if (!front) {
flag = true;
continue;
}
if (flag)
return false;
q.push(front->_left);
q.push(front->_right);
}
return true;
}
三、难点讲解
1、层序遍历
利用队列先进先出的性质,每一次出队列都带上下一层的左右节点,直到队列为空,遍历结束。
2、完全二叉树检验
☆☆☆ 完全二叉树的检验可以复用层序遍历
完全二叉树的检验核心思路是:带二叉树走一遍层序遍历,如果遍历到一个空节点,将flag置为true,如果遍历到一个非空节点而且flag==true,说明一定不是完全二叉树,返回false。如果能走完全过程,返回true。
实例1:
输出:true 解释:最后一层前的每一层都是满的(即,节点值为 {1} 和 {2,3} 的两层),且最后一层中的所有节点({4,5,6})尽可能靠左。
实例2:
输出:false 解释:值为 7 的节点不满足条件「节点尽可能靠左」。
可参考:958. 二叉树的完全性检验 - 力扣(LeetCode)
四、测试函数
int main()
{
const char* str = "ABD##E#H##CF##G##";
int a = 0;
auto e = BinaryTreeCreate(str, strlen(str), &a);
cout << BinaryTreeSize(e) << endl;
cout << BinaryTreeSize(e) << endl;
cout << BinaryTreeLeafSize(e) << endl;
cout << BinaryTreeLevelKSize(e, 3) << endl;
cout << BinaryTreeFind(e, 'N') << endl;
BinaryTreePrevOrder(e);
cout << endl;
BinaryTreeInOrder(e);
cout << endl;
BinaryTreePostOrder(e);
cout << endl;
BinaryTreeLevelOrder(e);
cout<<BinaryTreeComplete(e);
return 0;
}