zoukankan      html  css  js  c++  java
  • 这是二叉搜索树吗?

    一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,

    • 其左子树中所有结点的键值小于该结点的键值;
    • 其右子树中所有结点的键值大于等于该结点的键值;
    • 其左右子树都是二叉搜索树。

    所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。

    给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。

    输入格式:

    输入的第一行给出正整数N(<=1000)。随后一行给出N个整数键值,其间以空格分隔。

    输出格式:

    如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出“YES”,然后在下一行输出该树后序遍历的结果。数字间有1个空格,一行的首尾不得有多余空格。若答案是否,则输出“NO”。

    输入样例1:

    7
    8 6 5 7 10 8 11
    

    输出样例1:

    YES
    5 7 6 8 11 10 8
    

    输入样例2:

    7
    8 10 11 8 6 7 5
    

    输出样例2:

    YES
    11 8 10 7 5 6 8
    

    输入样例3:

    7
    8 6 8 5 10 9 11
    

    输出样例3:

    NO
    #include <stdio.h>  
    #include <algorithm>  
    using namespace std;  
    int a[1003], n, k = 0, b[1003];   
    int check1(int l, int r)  
    {  
        if(l > r)  
            return 1;  
        int root = a[l];//把根节点拿出来   
        int i, j;  
        for(i = l + 1 ; i <= r && a[i] < root; i++);//根据二叉搜索树的性质,把左右子树分开   
        for(j = i ; j <= r ; j++)//检查右子树是不是都大于根   
        {  
            if(a[j] < root)  
                return 0;  
        }  
        if(check1(l + 1, i - 1) == 0)//递归地检查左右子树   
            return 0;  
        if(check1(i, r) == 0)  
            return 0;  
        b[k++] = a[l];//b保存后序遍历序列   
        return 1;  
    }  
    int check2(int l, int r)  
    {  
        if(l > r)  
            return 1;  
        int root = a[l];  
        int i, j;  
        for(i = l + 1 ; i <= r && a[i] >= root; i++);  
        for(j = i ; j <= r ; j++)  
        {  
            if(a[j] >= root)  
                return 0;  
        }  
        if(check2(l + 1, i - 1) == 0)  
            return 0;  
        if(check2(i, r) == 0)  
            return 0;  
        b[k++] = a[l];  
        return 1;  
    }  
    int main()  
    {  
        int i;  
        scanf("%d", &n);  
        for(i = 1 ; i <= n ; i++)  
            scanf("%d", &a[i]);  
        if(n == 1)  
        {  
            printf("YES
    %d
    ", a[1]);  
            return 0;  
        }  
        if(a[1] > a[2])  
        {  
            if(check1(1, n))  
            {  
                printf("YES
    ");  
                for(i = 0 ; i < n - 1 ; i++)  
                    printf("%d ", b[i]);  
                printf("%d
    ", b[n - 1]);  
            }  
            else  
                printf("NO
    ");  
        }  
        else  
        {  
            if(check2(1, n))  
            {  
                printf("YES
    ");  
                for(i = 0 ; i < n - 1 ; i++)  
                    printf("%d ", b[i]);  
                printf("%d
    ", b[n - 1]);  
            }  
            else  
                printf("NO
    ");  
        }  
        return 0;  
    } 

    代码链接点击打开链接

    题目链接点击打开链接

    说实话此题的代码引起了我的深思,,

    后面的代码可以将前序遍历变成中序遍历

    #include <stdio.h>  
    #include <algorithm>  
    using namespace std;  
    int a[1003], n, k = 0, b[1003];   
    int check1(int l, int r)  
    {  
        if(l > r)  
            return 1;  
        int root = a[l];//把根节点拿出来   
        int i, j;  
        for(i = l + 1 ; i <= r && a[i] < root; i++);//根据二叉搜索树的性质,把左右子树分开   
        for(j = i ; j <= r ; j++)//检查右子树是不是都大于根   
        {  
            if(a[j] < root)  
                return 0;  
        }  
        if(check1(l + 1, i - 1) == 0)//递归地检查左右子树   
            return 0; 
    		 b[k++] = a[l];  ////////////(重要位置)递归的重要 
        if(check1(i, r) == 0)  
            return 0;  
        
        return 1;  
    }  
    int check2(int l, int r)  
    {  
        if(l > r)  
            return 1;  
        int root = a[l];  
        int i, j;  
        for(i = l + 1 ; i <= r && a[i] >= root; i++);  
        for(j = i ; j <= r ; j++)  
        {  
            if(a[j] >= root)  
                return 0;  
        }  
        if(check2(l + 1, i - 1) == 0)  
            return 0;  
    		 b[k++] = a[l]; /////////// (重要位置)递归的重要 
        if(check2(i, r) == 0)  
            return 0;  
       
        return 1;  
    }  
    int main()  
    {  
        int i;  
        scanf("%d", &n);  
        for(i = 1 ; i <= n ; i++)  
            scanf("%d", &a[i]);  
        if(n == 1)  
        {  
            printf("YES
    %d
    ", a[1]);  
            return 0;  
        }  
        if(a[1] > a[2])  
        {  
            if(check1(1, n))  
            {  
                printf("YES
    ");  
                for(i = 0 ; i < n - 1 ; i++)  
                    printf("%d ", b[i]);  
                printf("%d
    ", b[n - 1]);  
            }  
            else  
                printf("NO
    ");  
        }  
        else  
        {  
            if(check2(1, n))  
            {  
                printf("YES
    ");  
                for(i = 0 ; i < n - 1 ; i++)  
                    printf("%d ", b[i]);  
                printf("%d
    ", b[n - 1]);  
            }  
            else  
                printf("NO
    ");  
        }  
        return 0;  
    } 

    代码链接点击打开链接

  • 相关阅读:
    web前端的发展态势
    AngularJs 简单入门
    css代码优化篇
    git提交报错:Please make sure you have the correct access rights and the repository exists.
    Activiti工作流框架学习
    遍历map集合的4种方法
    js设置日期、月份增加减少
    Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
    webservice_rest接口_学习笔记
    相互匹配两个list集合+动态匹配${}参数
  • 原文地址:https://www.cnblogs.com/Nlifea/p/11746071.html
Copyright © 2011-2022 走看看