L3-010 是否完全二叉搜索树
这道题的难度在判断完全二叉树上。
首先复习一下概念
满二叉树
一棵深度为k,且有2^k-1个节点的树是满二叉树。
另一种定义:除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。这两种定义是等价的。
从树的外形来看,满二叉树是严格三角形的,如下图:
所有内部节点都有两个子节点,最底一层是叶子节点。
完全二叉树
完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h 层所有的结点都连续集中在最左边,这就是完全二叉树。
满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树。
下面是完全二叉树的基本形态:
接着来说说如何判断
1.如果树为空,一定不是
2.如果树不为空,BFS层序遍历这棵树。
如果一个结点左右孩子都不为空,将其左右孩子入队列;
如果遇到一个结点,左孩子为空,右孩子不为空,则该树一定不是完全二叉树;
如果遇到一个结点,左孩子不为空,右孩子为空;或者左右孩子都为空;则该节点之后的队列中的结点都为叶子节点;该树才是完全二叉树,否则就不是完全二叉树;
详见代码~
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<string.h> #include<math.h> #include<queue> #define maxn 1000005 using namespace std; typedef long long ll; struct node { int data; node *l,*r; }; int n,flag,cnt; int a[maxn],id[maxn]; node *build(node *root,int v) { node *t; if(root==NULL) { t=new node; t->data=v; t->l=t->r=NULL; return t; } if(v>root->data) root->l=build(root->l,v); else root->r=build(root->r,v); return root; } void BFS(node *root) { int tmp=0; node *tn=new node; queue<node*> q; q.push(root); while(!q.empty()) { tn=q.front(); q.pop(); printf("%d",tn->data); tmp++; if(tmp<n) printf(" "); if(tn->l!=NULL) q.push(tn->l); if(tn->r!=NULL) q.push(tn->r); } printf("\n"); } void judge(node *root) { node *tm=new node; if(root==NULL) { printf("NO\n"); return; } queue<node*> q; q.push(root); while(!q.empty()) { tm=q.front(); q.pop(); if(flag&&(tm->l||tm->r)) { printf("NO\n"); return; } if(tm->l&&tm->r) { q.push(tm->l); q.push(tm->r); } else if(!tm->l&&tm->r) { printf("NO\n"); return; } else if(tm->l&&!tm->r) { if(tm->l->l||tm->l->r) { printf("NO\n"); return; } flag=1; q.push(tm->l); } else flag=1; } printf("YES\n"); return; } int main() { node *root=NULL; flag=0; cnt=0; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&a[i]); root=build(root,a[i]); } BFS(root); judge(root); return 0; }