解决此问题关键点就是理解完全二叉树的特点,完全二叉树定义如下:
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。如下图:
判断一棵树是否为完全二叉树主要使用的算法是层序遍历,在层序遍历中,只要遇到一个节点的左右子树之一不为空,则立即将标志位置为true,在后面的子树中若遇到不为空的节点则该树不是完全二叉树,否则为完全二叉树,实现方法写在一个搜索树的类中,方面测试。
代码如下:
#pragma once
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
//判断一棵树是否是完全二叉树
//完全二叉树最后一层节点全部集中在左子树或者最后一层都有节点,没有空节点
//1。在层序遍历时,若遇到一个空节点,则此节点后的所有节点均为空,若不为空则该树不是完全二叉树
template<class T>
struct BSNode
{
int key;
BSNode* left;
BSNode* right;
BSNode* parent;
BSNode(T value) :
key(value)
, left(NULL)
, right(NULL)
, parent(NULL)
{}
};
template<class T>
class BSTree
{
typedef BSNode<T> Node;
public:
BSTree() :
_root(NULL)
{}
~BSTree()
{}
private:
bool RCheck(queue<Node*> &q)
{
while (!q.empty())
{
Node* cur = q.front();
if (flag && cur->left != NULL)
{
return false;
}
else if (cur->left == NULL)
{
flag = true;
}
if (cur->right == NULL)
{
flag = true;
}
else if (flag && cur != NULL)
{
return false;
}
if (cur->left != NULL)
{
q.push(cur->left);
}
if (cur->right != NULL)
{
q.push(cur->right);
}
q.pop();
}
return true;
}
public:
bool CheckCompleteTree()
{
if (_root == NULL)
{
return true;
}
queue<Node*> q;
q.push(_root);
return RCheck(q);
}
public:
void Insert(T key)
{
Node* newnode = new Node(key);
if (_root == NULL)
{
_root = newnode;
}
else
{
Node* cur = _root;
Node* parent = NULL;
while (cur)
{
parent = cur;
if (key > cur->key)
{
cur = cur->right;
}
else if (key < cur->key)
{
cur = cur->left;
}
else
{
return;
}
}
if (parent->key > key)
{
parent->left = newnode;
}
else
{
parent->right = newnode;
}
newnode->parent = parent;
}
}
private:
BSNode<T>* _root;
};
运行结果如下:
二叉树如下:
二叉树如下时: