完全二叉树概念
若设二叉树的深度为h,除第h 层外,其它各层(1~h-1) 的结点数都达到最大个数,第h 层所有的结点都连续集中在最左边,这就是完全二叉树
思路 :利用队列queue实现(层序遍历思想)
1、如果树为空,则直接返回false
2、如果树不为空:层序遍历二叉树
(1)如果一个结点左右孩子都不为空,则pop该节点,且将其左右孩子入队列;
(2)如果遇到一个结点,左孩子为空,右孩子不为空,则该树一定不是完全二叉树;
(3)如果遇到一个结点,左孩子不为空且右孩子为空(此时应将左孩子push进队列中),或者左右孩子都为空;如果该节点之后的队列中的所有结点都为叶子节点,则该树就是完全二叉树,否则就不是完全二叉树
代码:
#include<iostream>
#include<queue>
using namespace std;
struct Node
{
int _data;
Node* _left;
Node* _right;
Node(int x)
:_data(x)
, _left(NULL)
, _right(NULL)
{}
};
class BinaryTree
{
public:
//二叉树的构建
BinaryTree(const int a[], int size, int invalide)
{
int index = 0;
_root = _CreateBinaryTree(a, size, index, invalide);
}
Node* _CreateBinaryTree(const int a[], int size, int &index, int invalide)
{
Node* root = NULL;
if (index < size && a[index] != invalide)
{
root = new Node(a[index]);
root->_left = _CreateBinaryTree(a, size, ++index, invalide);
root->_right = _CreateBinaryTree(a, size, ++index, invalide);
}
return root;
}
//判断是否为完全二叉树
bool IsCompleteBinaryTree()
{
if (_root == NULL)
return false;
queue<Node*> q;
q.push(_root);
while (!q.empty())
{
Node* cur = q.front();
//左右孩子均不为空
if (cur->_left&&cur->_right)
{
q.pop();
q.push(cur->_left);
q.push(cur->_right);
}
//左孩子为空且右孩子不为空
if (cur->_left == NULL && cur->_right != NULL)
return false;
//左孩子不为空且右孩子为空,左右孩子均为空
if ((cur->_left&&cur->_right == NULL) || (cur->_left == NULL&&cur->_right == NULL))
{
//左孩子不为空时,将左孩子push进队列
if (cur->_left&&cur->_right == NULL)
q.push(cur->_left);
q.pop();
while (!q.empty())
{
cur = q.front();
if (cur->_left == NULL && cur->_right == NULL)
q.pop();
else
return false;
}
return true;
}
}
return true;
}
private:
Node* _root;
};
int main()
{
int msg[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6, '#', '#' };
BinaryTree tr(msg, 12, '#');
cout << tr.IsCompleteBinaryTree() << endl;
system("pause");
return 0;
}