【编程题目】判断整数序列是不是二元查找树的后序遍历结果,如果是,构建该二元查找树

判断整数序列是不是二元查找树的后序遍历结果
题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
如果是返回 true,否则返回 false。
例如输入 5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:
8
/ \
6 10
/ \ / \
5 7 9 11
因此返回 true。
如果输入 7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回 false。

做这个题目的时候最开始傻了,想着从前到后根据数字的大小关系判断。后来幡然醒悟,根据后序遍历的特点。序列最后一个数字就是根节点数字,只要从后向前依次把数字插入的二元查找树中就可以了。

树一定是可以构建成功的,因为我们只不过是不停的插入数据罢了。 但是这个构建的树 是否符合 后序遍历的结果是 给定序列则不一定了。 需要判断。

判断的原则:

因为我们插入数字是从序列的后面往前面插入。这说明,先插入的点应该在后序遍历的后面出现, 如果一棵树的某个节点的左子树已经被构建了,就说明之后不应该再访问其右子树了, 因为遍历过程中先访问左子树,后访问右子树。根据此可以判定输入序列是否合法。

代码: 写了一晚上,构建失败时后序遍历释放内存后 出函数后 T虽然被释放了 但不是我想要的NULL 而是一个随意的值。不知道哪里有问题。 但整体的功能是都正确的。

代码功能:根据输入判断是否是一个二元查找树后序遍历结果,如果是,构建该二元查找树。

#include<stdio.h>
#include<stdlib.h>
#include<vector>
using namespace std;
typedef struct BinaryTree
{
    int data;
    struct BinaryTree *rchild, *lchild;
}BinaryTree;

void visit(BinaryTree * &p)
{
    if(p != NULL)
    {
        free(p);
        p = NULL;
    }
}

int AferOrderTraverse(BinaryTree *&T) //后序遍历
{
    BinaryTree * p;
    vector<BinaryTree *> Stack;
    int tag[30] = {0}; //用tag标签记录存入的是左子树0 还是右子树1
    int tagnum = 0; //记录存放的数量
    Stack.push_back(T);
    tag[0] = 0;
    tagnum = 1;

    while(!Stack.empty())
    {
        while((p = Stack.back())!= NULL)
        {
            Stack.push_back(p->lchild);
            tag[tagnum++] = 0;
        }
        //只要右子树弹出,其双亲结点就被访问并弹出
        while(tag[tagnum - 1] == 1)  //若是右子树 先弹出开始的空集 访问其parent结点(一定是其上一个结点) 再循环弹出
        {
            Stack.pop_back();
            tagnum--;
            visit(Stack.back());
        }
        Stack.pop_back();
        tagnum--;

        if(!Stack.empty())
        {
            p = Stack.back();
            Stack.push_back(p->rchild);
            tag[tagnum++] = 1;
        }
    }
    return 0;
}

//输入,待构造的数组, 数组的长度 和待返回的二元查找树 返回1 说明构造成功 返回0 说明构造失败
int TreeFromAfterOrder(int * in, int leng, BinaryTree * &T)
{
    int n = leng;
    T = NULL;  //令树根初始为空
    while(n != 0) //从后向前 一次插入结点
    {
        BinaryTree * tmp = (BinaryTree *)malloc(sizeof(BinaryTree));  //构造当前带插入的结点
        tmp->data = in[n - 1];   //当前待插入的数据
        tmp->lchild = NULL;
        tmp->rchild = NULL;
        if(T == NULL)  //如果根是空的 把当前结点设为根
        {
            T = tmp;
        }
        else  //如果根不是空的
        {
            BinaryTree * x = T;
            BinaryTree *px = NULL;
            while(x != NULL)   //循环查找应该插入的位置 并判断是否合法
            {
                if(tmp->data > x->data)
                {
                    if(x->lchild != NULL) //向右移动时 必须左子树为空 因为从后向前依次插入点 如果左子树不为空说明 右子树应该已经访问完毕 不应该再次访问了 否则不满足后序遍历条件
                    {
                        AferOrderTraverse(T);  //不满足时后序遍历 释放已分配的内存
                        return 0;
                    }
                    else
                    {
                    px = x;
                    x = x->rchild;
                    }
                }
                else
                {
                    px = x;
                    x = x->lchild;
                }
            }
            if(tmp->data > px->data)
            {
                px->rchild = tmp;
            }
            else
            {
                px->lchild = tmp;
            }
        }
        n--;
    }
    return 1;
}
int main()
{
    int a[8] = {1,3,4,2,6,8,7,5};
    int b[4] = {7,4,6,5};

    BinaryTree * T = NULL;
    int result = TreeFromAfterOrder(b, 4, T);

    if(result == 1)
    {
        printf("success");
    }
    else
    {
        printf("wrong");
    }

    return 0;
}

【编程题目】判断整数序列是不是二元查找树的后序遍历结果,如果是,构建该二元查找树,布布扣,bubuko.com

时间: 2024-10-18 15:22:25

【编程题目】判断整数序列是不是二元查找树的后序遍历结果,如果是,构建该二元查找树的相关文章

判断一个序列是否是一个二叉查找树的后序遍历结果

题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果.如果是返回 true,否则返 回 false . 例如输入 5.7.6.9.11 .10.8,由于这一整数序列是如下树的后序遍历结果: 8 / \ 6 10 / \ / \ 5 7 9 11 因此返回 true. 如果输入 7.4.6.5,没有哪棵树的后序遍历的结果是这个序列,因此返回 false . 思路:对于树的很多问题都是可以使用递归来解决.这道题也不例外.首先明白后序遍历的特点,最后一个是根元素.左子树都比根元素打,右

微软算法100题09 判断整数序列是不是二元查找树的后序遍历结果

9. 判断整数序列是不是二元查找树的后序遍历结果题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果.如果是返回true,否则返回false.例如输入5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果:8/ \6 10/ \ / \5 7 9 11因此返回true.如果输入7.4.6.5,没有哪棵树的后序遍历的结果是这个序列,因此返回false. 思路:如果一个数组为BST的后序遍历结果 则最后一个元素必然为该BST的根节点 因为BST的特性是左子树必然全部小

9判断整数序列是不是二元查找树的后序遍历结果

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4252095.html 声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果.如果是返回true,否则返回false. 解题思路: 1.输入一个整型数组a,根据该数组创建二

第9题:判断整数序列是不是二元查找树的后序遍历结果

欢迎转载,转载请务必注明出处:http://blog.csdn.net/alading2009/article/details/44872143 第9题:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果.如果是返回true,否则返回false. 例如输入5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果: 因此返回true. 如果输入7.4.6.5,没有哪棵树的后序遍历的结果是这个序列,因此返回false. 由于二叉查找树的特性(左子树的值小于根节点,右子树的值

IT公司100题-9-判断整数序列是不是二元查找树的后序遍历结果

问题描述: 输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果. 如果是返回true,否则返回false. 例如输入4, 8, 6, 12, 16, 14, 10,由于这一整数序列是如下树的后序遍历结果: 10/     \6      14/  \    /   \4   8 12    16 因此返回true. 如果输入6, 5, 8, 5, 7 ,则返回false. 分析: 在后续遍历得到的序列中,最后一个元素为树的根结点.根节点元素将数组分为两部分,左边都小于根节点,右边都大

6.二元查找树的后序遍历结果

http://zhedahht.blog.163.com/blog/static/25411174200725319627/ 题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果.如果是返回true,否则返回false. 例如输入5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果: 8       /  \      6    10    / \    / \   5   7   9  11 因此返回true. 如果输入7.4.6.5,没有哪棵树的后序遍历的结

已知二叉树的先序遍历序列和中序遍历序列,输出该二叉树的后序遍历序列

题目描述 输入二叉树的先序遍历序列和中序遍历序列,输出该二叉树的后序遍历序列. 输入 第一行输入二叉树的先序遍历序列: 第二行输入二叉树的中序遍历序列. 输出 输出该二叉树的后序遍历序列. 示例输入 ABDCEF BDAECF 示例输出 DBEFCA #include <iostream> #include <cstring> #define MAX 50+3 using namespace std; typedef char Elem_Type; typedef struct B

判断数组是不是某二叉搜索树的后序遍历

题目:输入一个数组,判断数组是不是某二叉搜索树的后序遍历.输入的数组的任意两个数字都不相同 分析:要明白题目的意思,意思就是判断一个数组是否是某个搜索树的后序遍历.首先要搞清搜索树的含义:跟结点大于左子树而小于右子树.其次,数组的最后一个结点一定是后序遍历的根节点.所以我们只要满足这两个条件,再通过递归就可以解出来了.代码如下: // 二叉搜索树的遍历序列.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream

判断一个数组是否是一个二叉排序树的后序遍历结果

比如给出数组[5,7,6,9,11,10,8]判断其是否为二叉排序树的后序遍历结果,也就是能不能画出一个二叉排序树使其的后序遍历结果与这个数组相同,若可以返回true,不可以返回false. 代码: int is_valid(int *data, int n){ if(data==NULL)return 0; int left=1; int right=1; int i=0; int j; int root=data[n-1]; while(data[i]<root){ i++; } for(j