判断一颗树是不是完全二叉树
程序员文章站
2022-06-05 20:14:10
...
首先我们要明白完全二叉树的含义:
完全二叉树:
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左
边,这就是完全二叉树
我们先来回顾下二叉树按层遍历,先将根节点进队列,然后判断每次这个队列是否为空,不为空,每次取队头的数据然后pop,最后再递归走其子问题,判断左子树是否为空,不为空直接入队,再判断右子树是否为空,不为空直接入队.这样所有的元素都可以入队;我们再从细节观察如何出队.
//二叉树的层序遍历
void LevelOrder(BSTreeNode*root)
{
queue<BSTreeNode*>q;
if (root)
{
q.push(root);
}
while(!q.empty())
{
BSTreeNode*front = q.front();
q.pop();
cout <<front->_data << " ";
if (front->left)
{
q.push(front->left);
}
if (front->right)
{
q.push(front->right);
}
}
cout << endl;
}
完全二叉树如何判断呢?
根据前面的概念,判断完全二叉树,每次都是递归走子问题,当前层是否满足条件,当前层满足后再判断下一层,每次都是递归走子问题.这个过程和层序遍历很像,不过加了判断条件:是否满足完全二叉树的性质.
我们列出不满足的情况
1:当前层节点不连续
2:当前层没有孩子节点
可能这样还是会比较麻烦,那么我们通过一种方式:
用一个标签来标记,就会省去很多不必要以及重复的操作:
bool IsCompleteTree(BSTreeNode*root)
{
queue<BSTreeNode*>q;
if (root)
q.push(root);
bool tag = true;//表明有孩子
while (!q.empty())
{
BSTreeNode*front = q.front();
q.pop();
if (front->left)
{
//表明没有孩子
if (tag == false)
{
//当前层不是完全二叉树
return false;
}
q.push(front->left);
}
else
{
//没有孩子
tag = false;
}
if (front->right)
{
//表明没有孩子
if (tag == false)
{
//当前层不是完全二叉树
return false;
}
q.push(front->right);
}
else
{
tag = false;
}
}
return true;
}
验证:
#include<iostream>
#include<queue>
#include<string>
using namespace std;
struct BSTreeNode
{
int _data;
BSTreeNode*left;
BSTreeNode*right;
BSTreeNode(int data)
:_data(data)
, left(NULL)
, right(NULL)
{}
};
void PrevInoer(BSTreeNode*root)
{
if (root == NULL)
return;
cout << root->_data << " ";
PrevInoer(root->left);
PrevInoer(root->right);
}
//二叉树的层序遍历
void LevelOrder(BSTreeNode*root)
{
queue<BSTreeNode*>q;
if (root)
{
q.push(root);
}
while(!q.empty())
{
BSTreeNode*front = q.front();
q.pop();
cout <<front->_data << " ";
if (front->left)
{
q.push(front->left);
}
if (front->right)
{
q.push(front->right);
}
}
cout << endl;
}
//二叉树层序遍历的变形(判断一颗树是不是完全二叉树)
/*判断一颗树是不是完全二叉树,它的上一层必须是完全二叉树*/
bool IsCompleteTree(BSTreeNode*root)
{
queue<BSTreeNode*>q;
if (root)
q.push(root);
bool tag = true;//表明有孩子
while (!q.empty())
{
BSTreeNode*front = q.front();
q.pop();
if (front->left)
{
//表明没有孩子
if (tag == false)
{
//当前层不是完全二叉树
return false;
}
q.push(front->left);
}
else
{
//没有孩子
tag = false;
}
if (front->right)
{
//表明没有孩子
if (tag == false)
{
//当前层不是完全二叉树
return false;
}
q.push(front->right);
}
else
{
tag = false;
}
}
return true;
}
void Test()
{
BSTreeNode*node1 = new BSTreeNode(1);
BSTreeNode*node2 = new BSTreeNode(2);
BSTreeNode*node3 = new BSTreeNode(3);
BSTreeNode*node4 = new BSTreeNode(4);
BSTreeNode*node5 = new BSTreeNode(5);
BSTreeNode*node6 = new BSTreeNode(6);
node1->left = node2;
node1->right = node5;
node2->left = node3;
node2->right = node4;
node5->left = node6;
PrevInoer(node1);
cout << endl;
cout << "LevelOrder?" << LevelOrder(node1) << endl;
cout << "IsCompleteTree?" << IsCompleteTree(node1) << endl;
}
int main()
{
Test();
system("pause");
return 0;
}
下一篇: 对数组的轴和轴计算的理解