参考层序遍历的算法,利用队列作为储存结构,将二叉树从上到下,从左到右遍历,对于完全二叉树来说,一旦队列中读到空指针,则必定已将二叉树遍历完全了,否则若空指针后还有为访问的元素,则不是完全二叉树。
思路:
遍历二叉树,直到结尾(nullptr)
→ 当前节点不存在,空树或者叶子节点,返回真【出口A】
→当前节点存在,入队
→→队列非空,取队首元素
→→→队首是叶子 && 存在左右儿子 || 队首存在右儿子但是不存在左儿子,返回false【出口B】
→→→队首有左儿子,左儿子入队
→→→队首有右儿子,右儿子入队
→→→队首有左儿子没有儿子,是叶子节点;队首没有有左儿子没有右儿子,叶子节点
struct node{
node left;
node right;
int value;
};
bool isCBT(node head){
if(!head)
return true;
bool leaf = true;
queue<node> q;
q.push(head);//根节点入队
while(!q.empty()){
node temp = q.front();
q.pop();
if((leaf && (temp->left|| temp->right)) || (!temp->left && temp->right))
return false;//叶子节点存在左或者右儿子,当前节点有右儿子无左儿子
if(temp->left)//有左儿子
q.push(temp->left);
if(temp->right)//有右儿子
q.push(temp.right);
if(temp->left&&(!temp->right) || (!temp->left)&&(!temp->right))
leaf = true;//叶节点是有没有左儿子和右儿子,有左儿子,没有右儿子
}
return true;
}
测试代码:
#include<iostream>
#include<stdlib.h>
#include<stack>
#include<queue>
using namespace std;
#define len 15 //定义一个长度
typedef int ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
typedef struct Node
{
BiTree btnode;
bool isfirst;
}Node,*node;
//判断是否是完全二叉树
bool isCBT(BiTree head){
if(!head)
return true;
bool leaf = true;
queue<BiTree> q;
q.push(head);//根节点入队
while(!q.empty()){
BiTree temp = q.front();
q.pop();
if((leaf && (temp->lchild|| temp->rchild)) || (!temp->lchild && temp->rchild))
return false;//叶子节点存在左或者右儿子,当前节点有右儿子无左儿子
if(temp->lchild)//有左儿子
q.push(temp->lchild);
if(temp->rchild)//有右儿子
q.push(temp->rchild);
if(temp->lchild&&(!temp->rchild) || (!temp->lchild)&&(!temp->rchild))
leaf = true;//叶节点是有没有左儿子和右儿子,有左儿子,没有右儿子
}
return true;
}
int main()
{
int a[len] = { 62, 88, 58, 47, 35, 73, 51, 99, 37, 93, 23, 27, 45, 21, 12 };
BiTree tree = NULL;
CreateOrderBinaryTree(tree, a);
cout << "判断是否是完全二叉树" << endl;
if(isCBT(tree)) cout<<"是完全二叉树"<<endl;
else cout<<"不是完全二叉树"<<endl;
return 0;
}
测试结果:
参考:https://blog.csdn.net/qq_40938077/article/details/80471997