判断一棵树是否为完全二叉树
程序员文章站
2022-06-05 20:15:00
...
完全二叉树的定义(Complete Binary Tree)
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。
一棵二叉树至多只有最下面的两层上的结点的度数可以小于2,并且最下层上的结点都集中在该层最左边的若干位置上,则此二叉树成为完全二叉树。
**简单来说,完全二叉树(深度为K)即为K-1层为满二叉树(左右子树都存在),最后一层(第K层)的结点都是从左到右依次排列,中间不能有空结点。
**
以三层为例,如图所示,图一图二为完全二叉树,图三图四不是完全二叉树。
判断完全二叉树的方法
判断完全二叉树类似与层序遍历,假设有如图所示的一颗二叉树。
首先将根结点放入队列中,如果不为空,那么再依次放入其左孩子和右孩子(空结点也入队列,此时的空结点也是队列中的数据),并且把对头的结点pop出去,递归直到遇到空结点为止。过程如表所示。
①当对头为空时,如果此时的队列除了空结点还有其它结点时,那么该二叉树一定不是完全二叉树。
②当对头为空时,如果此时的队列只有空结点,那么该二叉树一定为完全二叉树。
//判断二叉树是否为完全二叉树
bool _IsCompleteBinaryTree(Node* root)
{
//如果该二叉树为空树,那么为完全二叉树。
if (root == NULL)
return true;
//如果该二叉树只有一个结点,那么为完全二叉树。
if (root->_Left == NULL && root->_Right == NULL)
return true;
queue<Node*> q; //创建一个队列。
Node* ptr;
q.push(root); //先把根结点push到队列中。
//当对列头不为空时,递归push其左孩子和右孩子。并且把对头pop出队列。
while ((ptr = q.front()) != NULL)
{
q.pop();
q.push(ptr->_Left);
q.push(ptr->_Right);
}
while (q.empty() == false)
{
//依次出队列
ptr = q.front();
q.pop();
//把每次出队列的ptr和Null做判断,如果不相等,那么就不是完全二叉树。
if (ptr != NULL)
{
return false;
}
}
return true;
}
完整代码:
#include <iostream>
#include <queue>
using namespace std;
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode(const T data)
:_data(data)
,_Left(NULL)
,_Right(NULL)
{}
T _data;
BinaryTreeNode<T>* _Left;
BinaryTreeNode<T>* _Right;
};
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree()
:_root(NULL)
{}
BinaryTree(const T array[], size_t size, const T& invalid)
{
size_t index = 0;
_CreateTree(_root, array, size, invalid, index);
}
bool IsCompleteBinaryTree()
{
return _IsCompleteBinaryTree(_root);
}
private:
//创建二叉树
void _CreateTree(Node*& root, const T array[], size_t size, const T& invalid, size_t& index)
{
if (index < size && array[index] != invalid)
{
root = new Node(array[index]);
_CreateTree(root->_Left, array, size, invalid, ++index);
_CreateTree(root->_Right, array, size, invalid, ++index);
}
}
//判断二叉树是否为完全二叉树
bool _IsCompleteBinaryTree(Node* root)
{
//如果该二叉树为空树,那么为完全二叉树。
if (root == NULL)
return true;
//如果该二叉树只有一个结点,那么为完全二叉树。
if (root->_Left == NULL && root->_Right == NULL)
return true;
queue<Node*> q; //创建一个队列。
Node* ptr;
q.push(root); //先把根结点push到队列中。
//当对列头不为空时,递归push其左孩子和右孩子。并且把对头pop出队列。
while ((ptr = q.front()) != NULL)
{
q.pop();
q.push(ptr->_Left);
q.push(ptr->_Right);
}
while (q.empty() == false)
{
ptr = q.front();
q.pop();
//把每次出队列的ptr和Null做判断,如果不相等,那么就不是完全二叉树。
if (ptr != NULL)
{
return false;
}
}
return true;
}
private:
BinaryTreeNode<T>* _root;
};
int main()
{
char* ptr = "124###35##6";
BinaryTree<char> t(ptr, strlen(ptr), '#');
cout<<t.IsCompleteBinaryTree()<<endl;
}
上一篇: 苹果密谋全新系统:SiriOS!
下一篇: Hibernate 框架入门