【题目】
有一棵二叉树,请设计一个算法判断它是否是完全二叉树。
给定二叉树的根结点root,请返回一个bool值代表它是否为完全二叉树。树的结点个数小于等于500。
【分析】完全二叉树树主要有两点:
- 当一个结点有右孩子,但是没有左孩子,直接返回false
- 当一个节点有左孩子无右孩子,那么接下来要遍历的节点必须是叶子结点。(叶子结点左右孩子为空)
使用层次遍历并检查倒数第二层是否满以及是否有元素有右孩子无左孩子即可。
这两个条件看似比较简单,第二点我还是花了好长时间才理解,因为我当时楞是想不通下图中的情况:
图中的情况,红色结点左孩子有,右孩子为空,我没想明白怎么判断下一层还有结点的情况,甚至想到去统计个数,但是这样太复杂。事实上,只需要使用一个变量,leaf用来标记是否一个结点有左孩子无右孩子,如红色结点,leaf=true。我使用层次遍历,接下来会遍历到绿色节点,由于leaf为true,绿色结点不能有孩子,所以不满足,返回false。
【代码】
class CheckCompletion {
public:
bool chk(TreeNode* root){
return root == NULL ? false : check_detail(root);
}
private:
bool check_detail(TreeNode* t){
bool res = true;
queue<TreeNode*> que;
que.push(t);
while(!que.empty()){
for(int i=0; i<que.size(); ++i){
TreeNode* tmp = que.front();
que.pop();
if(tmp->left == NULL && tmp->right != NULL){
res = false;
break;
}
if(tmp->left != NULL)
que.push(tmp->left);
if(tmp->right != NULL)
que.push(tmp->right);
}
}
return res;
}
};