PTA 7-28 搜索树判断(镜像二叉搜索树的后序遍历)

算法源代码在 Veeupup Github

考点:

  • 二叉搜索树遍历方式和性质运用

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

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

输入格式:

输入的第一行包含一个正整数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

这道题想考二叉搜索树性质的运用以及二叉树的几种遍历方式,需要对二叉树的遍历方式和搜索二叉树的性质有比较好的理解,建议画图加深理解和推导。

思路:

对于给定的先序遍历序列,我们可以构建一颗二叉搜索树,然后根据生成的二叉搜索树的性质来做。

  1. 如果生成二叉搜索树的前序遍历序列和输入的序列的一致,那么直接输出后序遍历的值
  2. 如果不符合 1,那么需要和这棵树的镜像二叉搜索树的前序遍历进行比较,但我们此时不需要真的互换每个结点的左右结点,只需要在先序遍历时先访问右子结点,此时得到的序列就是镜像二叉树的序列

    当我们确定是镜像二叉树的序列的时候,我们就可以后序遍历,但此时后序遍历的顺序会有所区别,应该是先访问右子树,再访问左子树,最后访问本身结点的顺序来进行后序遍历,此时得到的就是镜像二叉树的后序遍历。

完整代码如下:

/*
    Author: Veeupup
 */
#include <iostream>
#include <vector>
using namespace std;

const int maxn = 1010;

vector<int> inputOrder, preStr, preMirrorStr,postStr, postMirrorStr; // 保存输入的前序遍历的值,保存生成二叉搜索树的序列

struct node
{
    int data;
    node *left, *right;
    node(int _data): data(_data), left(NULL), right(NULL) {}
};

void insert(node* &root, int val)
{
    if(root == NULL)
    {
        root = new node(val);
        return;
    }else if(val < root->data) {
        insert(root->left, val);
    }else {
        insert(root->right, val);
    }
}

// 后续遍历的值
void postOrder(node *root) {
    if(root == NULL)
        return;
    postOrder(root->left);
    postOrder(root->right);
    postStr.push_back(root->data);
}

void postMirrorOrder(node *root) {
    if(root == NULL)
        return;
    postMirrorOrder(root->right);
    postMirrorOrder(root->left);
    postMirrorStr.push_back(root->data);
}

void preOrder(node *root) {
    if(root == NULL)
        return;
    preStr.push_back(root->data);
    preOrder(root->left);
    preOrder(root->right);
}

void preMirrorOrder(node *root) {
    if(root == NULL)
        return;
    preMirrorStr.push_back(root->data);
    preMirrorOrder(root->right);
    preMirrorOrder(root->left);
}

int main()
{
    freopen("data.txt", "r", stdin);
    int n;
    scanf("%d", &n);
    int num;
    node *root = NULL;
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &num);
        insert(root, num);
        inputOrder.push_back(num);  //保存
    }
    preOrder(root);
    preMirrorOrder(root);
    if (inputOrder == preStr)
    {
        printf("YES\n");
        postOrder(root);
        for (int i = 0; i < postStr.size(); i++)
        {
            if(i > 0) {
                printf(" ");
            }
            printf("%d", postStr[i]);
        }
    }
    else if (inputOrder == preMirrorStr)
    {
        printf("YES\n");
        postMirrorOrder(root);
        for (int i = 0; i < postMirrorStr.size(); i++)
        {
            if(i > 0) {
                printf(" ");
            }
            printf("%d", postMirrorStr[i]);
        }
    }
    else
    {
        printf("NO\n");
    }

    return 0;
}

原文地址:https://www.cnblogs.com/veeupup/p/12632963.html

时间: 2024-08-28 05:14:30

PTA 7-28 搜索树判断(镜像二叉搜索树的后序遍历)的相关文章

20,判断是不是二叉搜索树的后序遍历《剑指offer》

题目: 给定一个序列,判断是不是二叉搜索树的后序遍历 思路: 递归版: 一个正确的后序遍历可以分为三段来看: 1:最后一个值是根节点   2:左子树节点(都比根节点值小) 3:右子树节点(都比根节点大) 且满足左子树个数加右子树个数等于N-1:(N为后序遍历的节点总个数) 左子树和右子树又可以进行同样的操作,,,perfect的递归定义哈 然后判断出口: 1,正确的出口,子树只有一个元素或者零个元素(这零就是为什么要多写一个函数的原因了..) 2,错误的出口,左子树加上右子树的个数不等于N-1

数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树

在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉搜索树.红黑树.线索二叉树,它们在解决实际问题中有着非常重要的应用.本文主要从概念和一些基本操作上进行分类和总结. 一.概念总揽 (1) 堆 堆(heap order)是一种特殊的表,如果将它看做是一颗完全二叉树的层次序列,那么它具有如下的性质:每个节点的值都不大于其孩子的值,或每个节点的值都不小于其孩子的值

判断序列是否是二叉树的后序遍历序列

这个题的意思就是给定一个序列,判断这个序列是否是某个二叉排序树的后序遍历序列,这个算法的方法主要是根据后序遍历的性质,首先这个序列的最后一个元素肯定是根元素,然后将序列从左往右遍历,找到第一个大于根元素的点,这个点左边的肯定是当前根的左子树,这个点的右边肯定是当前根的右子树,继续向后遍历,看右子树中是否有值小于根,如果有,则false,否则分左右子树分别再次调用函数进行判断.具体代码如下: 1 public class IsLastOrder{ 2 3 public boolean islast

二叉搜索树以及对二叉搜索树平衡调整

代码的思想和图片参考:好大学慕课浙江大学陈越.何钦铭的<数据结构> 我们首先介绍一下什么是二叉搜索树和二叉平衡树: 二叉搜索树:一棵二叉树,可以为空:如果不为空,满足以下性质1. 非空左子树的所有键值小于其根结点的键值.2. 非空右子树的所有键值大于其根结点的键值.3. 左.右子树都是二叉搜索树. 二叉搜索树操作的特别函数:Position Find( ElementType X, BinTree BST ):从二叉搜索树BST中查找元素X,返回其所在结点的地址,查找的次数取决于树的高度  

PTA L2-004 这是二叉搜索树吗?-判断是否是对一棵二叉搜索树或其镜像进行前序遍历的结果 团体程序设计天梯赛-练习集

L2-004 这是二叉搜索树吗? (25 分) 一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点, 其左子树中所有结点的键值小于该结点的键值: 其右子树中所有结点的键值大于等于该结点的键值: 其左右子树都是二叉搜索树. 所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树. 给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果. 输入格式: 输入的第一行给出正整数 N(≤).随后一行给出 N 个整数键值,其间以空格分隔. 输

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

L2-004. 这是二叉搜索树吗? 一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点, 其左子树中所有结点的键值小于该结点的键值: 其右子树中所有结点的键值大于等于该结点的键值: 其左右子树都是二叉搜索树. 所谓二叉搜索树的"镜像",即将所有结点的左右子树对换位置后所得到的树. 给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果. 输入格式: 输入的第一行给出正整数N(<=1000).随后一行给出N个整数键值,其间以空格分

L2-004. 这是二叉搜索树吗

L2-004. 这是二叉搜索树吗? 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点, 其左子树中所有结点的键值小于该结点的键值: 其右子树中所有结点的键值大于等于该结点的键值: 其左右子树都是二叉搜索树. 所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树. 给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍

数据结构-二叉搜索树(BST binary search tree)

本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 二叉搜索树简介 顾名思义,二叉搜索树是以一棵二叉树来组织的,这样的一棵树可以用一个链表数据结构来表示,每个节点除了key和卫星数据(除了二叉树节点的基本数据以外人为添加的数据,这些数据和树的基本结构无关),还有left.right.parent,分别指向节点的左孩子.右孩子和父节点,如果对应的节点不存在则指向NIL节点(因为最简单的二叉搜索树中的NIL节点里并没有有用的信息,所以在实现的时候简

L2-004 这是二叉搜索树吗? (25 分) (树)

链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805070971912192 题目: 一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点, 其左子树中所有结点的键值小于该结点的键值: 其右子树中所有结点的键值大于等于该结点的键值: 其左右子树都是二叉搜索树. 所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树. 给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其