数据结构习题——搜索树判断

对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。如果我们交换每个节点的左子树和右子树,得到的树叫做镜像二叉搜索树。

现在我们给出一个整数键值序列,请编写程序判断该序列是否为某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,如果是,则输出对应二叉树的后序遍历序列。

输入格式:

输入的第一行包含一个正整数N(≤1000),第二行包含N个整数,为给出的整数键值序列,数字间以空格分隔。

输出格式:

输出的第一行首先给出判断结果,如果输入的序列是某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,则输出YES,否侧输出NO。如果判断结果是YES,下一行输出对应二叉树的后序遍历序列。数字间以空格分隔,但行尾不能有多余的空格。

输入样例1:

7
8 6 5 7 10 8 11

输出样例1:

YES
5 7 6 8 11 10 8

输入样例2:

7
8 6 8 5 10 9 11

输出样例2:

NO

根据输入的序列分别创建一个普通搜索树和一个镜像搜索树。然后分别先序遍历两棵树并记录其结果,与输入的序列作对比,判断输入的序列是不是某棵二叉搜索树或镜像二叉搜索树

代码如下:

#include <stdio.h>
#include <stdlib.h>

typedef struct TNode{
    struct TNode *Left;
    struct TNode *Right;
    int Data;
}*BinTree;
BinTree Insert1(BinTree BST,int Data){   //创建正序二叉搜索树(左子树键值小于右子树)
    if(!BST){
        BST=(BinTree)malloc(sizeof(struct TNode));
        BST->Data=Data;
        BST->Left=BST->Right=NULL;
    }
    else{
        if(Data>=BST->Data){
            BST->Right=Insert1(BST->Right,Data);
        }
        else if(Data<BST->Data){
            BST->Left=Insert1(BST->Left,Data);
        }
    }
    return BST;
}
BinTree Insert2(BinTree BST,int Data){ //创建镜像二叉搜索树(左子树键值大于右子树)
    if(!BST){
        BST=(BinTree)malloc(sizeof(struct TNode));
        BST->Data=Data;
        BST->Left=BST->Right=NULL;
    }
    else{
        if(Data>=BST->Data){
            BST->Left=Insert2(BST->Left,Data);
        }
        else if(Data<BST->Data){
            BST->Right=Insert2(BST->Right,Data);
        }
    }
    return BST;
}

int Pre[1100];  //记录将搜索树进行前序遍历的结果
int Count=0;
void PreOrder(BinTree BT){  //进行前序遍历并将遍历结果存放于Pre中
    if(BT){
        Pre[Count++]=BT->Data;
        PreOrder(BT->Left);
        PreOrder(BT->Right);
    }
}
int blank=0; //blank协助空格输出
void PostOrder(BinTree BT){  //后续遍历输出二叉树
    if(BT){
        PostOrder(BT->Left);
        PostOrder(BT->Right);
        if(blank){
            printf(" ");
        }
        blank=1;
        printf("%d",BT->Data);
    }
}

int main(){
    int N;
    BinTree BT1=NULL; //BT1为普通二叉搜索树,BT2为镜像二叉搜索树
    BinTree BT2=NULL;
    scanf("%d",&N);
    int Data[N];  //存放输入的序列
    for(int i=0;i<N;i++){ //创建BT1和BT2
        scanf("%d",&Data[i]);
        BT1=Insert1(BT1,Data[i]);
        BT2=Insert2(BT2,Data[i]);
    }
    PreOrder(BT1);  //先序遍历BT1
    int i;
    for(i=0;i<N;i++){  //将输入的序列与先序遍历的序列对比,看是否相同,如果i==N就相同
        if(Data[i]!=Pre[i])
            break;
    }
    Count=0; //Count置为0
    PreOrder(BT2); //先序遍历BT2
    int j;
    for(j=0;j<N;j++){ 
        if(Data[j]!=Pre[j])
            break;
    }
    if(i==N){  //输入序列为普通搜索树先序遍历的序列的情况
        printf("YES\n");
        PostOrder(BT1);  //后序输出BT1
        printf("\n");
    }
    else if(j==N){ //输入序列为镜像搜索树先序遍历的序列的情况
        printf("YES\n");
        PostOrder(BT2);
        printf("\n");
    }
    else printf("NO\n");
    return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值