7-2 是否完全二叉搜索树 (30分)

在这里插入图片描述
分析:
本题关键是完全二叉搜索树的概念(或者说定义)
我第一次没弄清楚什么是完全二叉树的概念,以为只有一种情况左孩子为空,右孩子不空这样就不是完全二叉树了,并把它当成判断条件来写代码,结果导致测试点3,4,5没过在这里插入图片描述
我一开始疑惑为什么一边完美,另一边完全,会是NO,两边明明都是完全啊,合起来为完全嘛?(n脸懵逼)
原来是这样:
在这里插入图片描述在这里插入图片描述

左图左子树为完美二叉树,右图为完全二叉树,但整棵树不是完全二叉树,因为8号结点,按完美二叉树(右图)的次序应该也是12号,但它是8号,相对位置不一样,所以他不是完全二叉树。

所以判断完全二叉树的思路

首先每个二叉树都会有以下4种情况:

情况一:
在这里插入图片描述

情况二:
在这里插入图片描述

情况三:
在这里插入图片描述

情况四:
在这里插入图片描述

1:如果当前访问的节点的左右孩子是情况3,说明不是完全二叉树,直接返回false。

2:如果当前访问的节点的左右孩子是情况1,继续访问其他节点。

3:如果当前访问的节点的左右孩子是情况2或者情况4,那么就做一个判断(接下来访问的所有节点必须全部是叶子节点)。
具体代码看下面程序中的Pan(BinTree BST)函数。

#include<stdio.h>
#include<stdlib.h>
typedef struct TNode* BinTree;
struct TNode{
    int Data;
    BinTree Left;
    BinTree Right;
};
BinTree Insert( BinTree BST, int x )
{
    if(!BST){
        BST=(BinTree)malloc(sizeof(struct TNode));
        BST->Data=x;
        BST->Left=BST->Right=NULL;
    }
    else{
        if(x>BST->Data) BST->Left=Insert( BST->Left, x );
        else if(x<BST->Data) BST->Right=Insert( BST->Right, x );
    }
    return BST;
}
void Out(BinTree BST)
{
    int i,front=0,tail=0,p=0;
    BinTree a[30],x;
    a[++tail]=BST;
    while(tail!=front){
        x=a[++front];
        if(p==0) {
            printf("%d",x->Data);
            p=1;
        }
        else printf(" %d",x->Data);
        if(x->Left) a[++tail]=x->Left;
        if(x->Right) a[++tail]=x->Right;
    }
}
void Pan(BinTree BST)
{
    int i,front=0,tail=0,q=0;
    BinTree a[30],x;
    a[++tail]=BST;
    while(tail!=front){
        x=a[++front];
        if(!x->Left&&x->Right){
        	printf("\nNO");
        	return;
		}
        if(x->Left&&x->Right){
			a[++tail]=x->Left;
			a[++tail]=x->Right;
		}
        if(!x->Right&&x->Left){
			a[++tail]=x->Left;
			q=1;
		}
		if(!x->Right&&!x->Left) q=1;
		while(q==1&&tail!=front){
			x=a[++front];
			if(x->Left||x->Right){
				printf("\nNO");
        		return;
			}
		}
    }
    printf("\nYES");
}
int main()
{
    int n,i,x;
    BinTree BST=NULL;
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%d",&x);
        BST=Insert(BST, x);
    }
    Out(BST);
    Pan(BST);
    return 0;
}
  • 9
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值