判断一棵二叉树是否为完全二叉树
Posted 梅诺
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了判断一棵二叉树是否为完全二叉树相关的知识,希望对你有一定的参考价值。
1.完全二叉树的特点(来自专业定义)
看到上面完全二叉树的特点,我可以将其特点按照自己的理解归纳为以下几点:
(1):若二叉树最下面一层有节点出现,那么这个节点一定是是从左到右依次排列,若只有一个孩子,那么这个孩子一定是左孩子而不是右孩子(特殊情况,空树和只有根节点的树都是完全二叉树)。
(2)要么最后一层全为叶子节点,否则以它为根节点的孩子一定是从左依次排列的)。
2.解决这个问题的办法(全部采用广度优先遍历的方法进行遍历,并使用队列这个结构操作数据):
只要当前节点有一个孩子不为空,那么就将它的左右孩子都压入队列,出队列第一次遇到NULL节点时,做一个标记,直到队列为空后面都再无非空节点出现,那么它就一定是完全二叉树;反之若第一次出现NULL节点后再出现非空节点,那么它一定就不满足完全二叉树的定义。
3.代码实现
bool _IsCompleteTree(Node* root)
if (root == NULL)
return true;
if (root->_left == NULL&&root->_right == NULL)
return true;
queue<Node*> q;
bool flag = false;
q.push(root);
while (!q.empty())
Node* Front = q.front();
q.pop();
if (Front != NULL && (Front->_left || Front->_right))
q.push(Front->_left);
q.push(Front->_right);
if (Front == NULL)
flag = true;
else
flag = false;
if (flag == false)
return false;
else
return true;
(在这会出现bug,具体的问题出现紧跟着提出)
<strong style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="font-size:18px;">这样写,会有一种情况出现误判,解释如下:</span></strong>
第一次出现NULL节点后,将flag置为true,后面遇到一个非空节点再将flag置为false,此时队列不为空,继续出队列,遇到NULL节点将flag置为true,此时队列为空,出循环,很明显,这个时候得到的结果就是错误的。
所以为了解决这种情况的误判,我们必须做以标记,在第一次出现NULL节点时并且后面紧跟着有非空节点出现时,直接返回,没有再进行判断的必要了。修改后代码如下:
bool _IsCompleteTree(Node* root)
if (root == NULL)
return true;
if (root->_left == NULL&&root->_right == NULL)
return true;
queue<Node*> q;
bool flag = false;
int count = 0;
q.push(root);
while (!q.empty())
Node* Front = q.front();
q.pop();
if (Front != NULL && (Front->_left||Front->_right))
q.push(Front->_left);
q.push(Front->_right);
if (Front== NULL)
flag = true;
count++;
else
if (count == 1)
flag = false;
return flag;
else
flag = false;
if (flag == false)
return false;
else
return true;
<strong style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="font-size:18px;">测试用例可以多给以下几组:</span></strong>
int array[] = 1, 2, 3, '#', '#', 4, '#','#',5,6,'#','#',7,'#',8 ;//无左孩子,有右孩子
int array[] = 1, 2, 3, 8, '#', '#', '#', 4, '#', '#', 5, 6, '#', '#', 7 ;//最下面一层有一个孩子,且是左孩子
array[] = 1, 2, 3, '#', 9, 4, '#', '#', 5, 6, '#', '#', 7, '#', '#' ;//最下面一层有一个孩子,且是右孩子
int array[] = 1, 2, 3, '#', '#', 4, '#', '#', 5, 6, '#', '#', 7, '#', '#' ;//最下面一层全部是叶子节点
int array[] = 1, 2, 3, 8, '#', '#','#', 4,9, '#', '#','#', 5, 6, '#', '#', 7 ;//上迎面解释的这种情况
int array[] = 1 ;//只有一个根节点
int array[] = NULL;//空树
以上是关于判断一棵二叉树是否为完全二叉树的主要内容,如果未能解决你的问题,请参考以下文章