• PTA-L2-004 这是二叉搜索树吗?


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

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

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

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

    输入格式:

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

    输出格式:

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

    输入样例 1:

    1. 7
    2. 8 6 5 7 10 8 11

    输出样例 1:

    1. YES
    2. 5 7 6 8 11 10 8

    输入样例 2:

    1. 7
    2. 8 10 11 8 6 7 5

    输出样例 2:

    1. YES
    2. 11 8 10 7 5 6 8

    输入样例 3:

    1. 7
    2. 8 6 8 5 10 9 11

    输出样例 3:

    NO

    解析:正常的二叉搜索树是左儿子都小于父节点,右儿子全都大于等于父节点,所谓镜像,就是反一下,是左儿子都大于等于父节点,右儿子全都小于父节点,因此我们可以分两个DFS来判断,每次取出左右儿子的所在段落分别递归即可,最后判断存的节点个数是否为N个,如果两个DFS都小于N个,那么就是不合法。

    如图:|_u_|__L__|___R__|,合法的子树均满足这样的情况,两段性。

    1. #include
    2. using namespace std;
    3. const int N=1e3+5;
    4. int n,a[N];
    5. vector<int> x,y;//分别存正常和镜像的后序遍历节点
    6. void dfs1(int l,int r)//小-大
    7. {
    8. if(l>r) return;
    9. int tl=-1,tr=-1,root=a[l];
    10. for(int i=l+1;i<=r;i++)
    11. {
    12. if(a[i]
    13. else break;
    14. }
    15. for(int i=r;i>=l+1;i--)
    16. {
    17. if(a[i]>=root) tr=i;
    18. else break;
    19. }
    20. //因此[l+1,tl]均小于root,[tr,r]均大于等于root
    21. if(tl!=-1) dfs1(l+1,tl);
    22. if(tr!=-1) dfs1(tr,r);
    23. x.push_back(root);
    24. }
    25. void dfs2(int l,int r)//大-小
    26. {
    27. if(l>r) return;
    28. int tl=-1,tr=-1,root=a[l];
    29. for(int i=l+1;i<=r;i++)
    30. {
    31. if(a[i]>=root) tl=i;
    32. else break;
    33. }
    34. for(int i=r;i>=l+1;i--)
    35. {
    36. if(a[i]
    37. else break;
    38. }
    39. if(tl!=-1) dfs2(l+1,tl);
    40. if(tr!=-1) dfs2(tr,r);
    41. y.push_back(root);
    42. }
    43. void solve()
    44. {
    45. scanf("%d",&n);
    46. for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    47. dfs1(1,n),dfs2(1,n);
    48. if(x.size()==n)
    49. {
    50. printf("YES\n");
    51. for(int i=0;isize();i++)
    52. {
    53. if(i!=0) printf(" ");
    54. printf("%d",x[i]);
    55. }
    56. printf("\n");
    57. return;
    58. }
    59. if(y.size()==n)
    60. {
    61. printf("YES\n");
    62. for(int i=0;isize();i++)
    63. {
    64. if(i!=0) printf(" ");
    65. printf("%d",y[i]);
    66. }
    67. printf("\n");
    68. return;
    69. }
    70. printf("NO\n");
    71. }
    72. int main()
    73. {
    74. // freopen("input.txt","r",stdin);
    75. // freopen("output.txt","w",stdout);
    76. int t=1;
    77. //scanf("%d",&t);
    78. while(t--) solve();
    79. return 0;
    80. }
  • 相关阅读:
    .NET 中的反射
    猿创征文|OpenCV编程——计算机视觉的登堂入室
    Qt文件系统源码分析—第二篇QSaveFile
    Geoserver+mysql+openlayers
    线程的状态
    内存模型之有序性
    CentOS7安装MySQL8
    JDK1.8的安装与配置
    高维统计理论 Gauss与Rademacher复杂度
    一起学数据结构(9)——二叉树的链式存储及相关功能实现
  • 原文地址:https://blog.csdn.net/qq_63739337/article/details/137871847