问题描述
判定一棵二叉树是否是完全二叉树。二叉树定义如下:
struct node {
int data;
struct node* left;
struct node* right;
};
typedef struct node BinaryTree;
完全二叉树的定义:若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
如下图中a为完全二叉树,而b不是完全二叉树。
分析
有如下算法,按层次(从上到下,从左到右)遍历二叉树,当遇到一个结点的左孩子为空时,则该结点右孩子必须为空,且后面遍历的结点左右孩子都必须为空,否则不是完全二叉树。
bool IsCompleteBinaryTree(BinaryTree * pRoot)
{
if(pRoot == NULL)
return false;
queue<BinaryTree *> q;
q.push(pRoot);
bool mustHaveNoChild = false;
bool result = true;
while(!q.empty())
{
BinaryTree * pNode = q.front();
q.pop();
if(mustHaveNoChild) // 已经出现了有空子树的节点了,后面出现的必须为叶节点(左右子树都为空)
{
if(pNode->m_pLeft != NULL || pNode->m_pRight != NULL)
{
result = false;
break;
}
}
else
{
if(pNode->m_pLeft != NULL && pNode->m_pRight != NULL)
{
q.push(pNode->m_pLeft);
q.push(pNode->m_pRight);
}
else if(pNode->m_pLeft != NULL && pNode->m_pRight == NULL) //左孩子不为空,右孩子为空,则后面结点左右子树必须为空
{
mustHaveNoChild = true;
q.push(pNode->m_pLeft);
}
else if(pNode->m_pLeft == NULL && pNode->m_pRight != NULL) //左孩子为空,右孩子不为空,则不是完全二叉树
{
result = false;
break;
}
else //左右孩子都为空
{
mustHaveNoChild = true;
}
}
}
return result;
}
参考资料