判断一棵二叉树是否为完全二叉树

来源:互联网 发布:mt4软件 编辑:程序博客网 时间:2024/05/22 02:07

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};//空树


0 0