參考層序遍歷的算法,利用隊列作爲儲存結構,將二叉樹從上到下,從左到右遍歷,對於完全二叉樹來說,一旦隊列中讀到空指針,則必定已將二叉樹遍歷完全了,否則若空指針後還有爲訪問的元素,則不是完全二叉樹。
思路:
遍歷二叉樹,直到結尾(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