uva536_树的重建(由先序,中序历遍推出后续历遍)



///////////////////////////////////////////////////////////////////////////////////////////////////////

作者:tt2767

声明:本文遵循以下协议自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0

查看本文更新与讨论请点击:http://blog.csdn.net/tt2767

链接被删请百度: CSDN tt2767

///////////////////////////////////////////////////////////////////////////////////////////////////////



详细写在注释中了:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<stack>
using namespace std;

const int  N  =  100000 + 10;
char pre_order[N],in_order[N];
stack<char> after_order;
int k = 0;

void build( int l1 ,int r1 ,int l2 ,int r2 );

int main()
{
    while(scanf("%s%s",pre_order,in_order) == 2)
    {
        int l = strlen(pre_order);
        k = 0;
        build(0,l-1,0,l-1);//建立后序历遍
        while(!after_order.empty())//栈后进先出,顺序正好为后序历遍
        {
            printf("%c",after_order.top());
            after_order.pop();
        }
        puts("");
    }
    return 0;
}

void build( int l1 ,int r1 ,int l2 ,int r2 )//由先序中序直接求出后序
{
    if( (l1 > r1 ) || (l2 > r2) )   return ;
    char root = pre_order[l1];
    after_order.push(root);       //每次把根压入栈中
    int p = l2; //每次从本次开始的地方寻找根
    while(in_order[p] != root) p++; //找到中序历遍中根的位置
    int cnt = p-l2;   //左子树的个数
    build(l1+cnt+1,r1,p+1,r2);//先建右子树,后建左子树
    build(l1+1,l1+cnt,l2,p-1);
}

版权声明:本文为博主原创文章,允许非商业性转载,转载必须著名作者(CSDN tt2767)与本博客链接:http://blog.csdn.net/tt2767。

时间: 2024-10-04 22:27:49

uva536_树的重建(由先序,中序历遍推出后续历遍)的相关文章

先序中序求解二叉树(使用二叉查找树原理)

 二叉树的先序中序序列确定,二叉树也就确认了,但还原二叉树确实有点麻烦,要不断的遍历中序序列.后来学习了二叉查找树,发现了一个很巧的办法. 二叉查找树的特性是每个节点都有权值,其规律为左子节点小于父节点,右子节点大于父节点,其中序序列是有序的.如果我们把二叉树变成二叉查找树,就是要给每个子节点赋值,最简单的根据中序序列从0->赋值,现在我们来看看二叉查找树先序序列和二叉查找树的关系.以下树的中序序列为DBEGACF,附上权值为(D:0,B:1,E:2,G:3,A:4,C:5,F:6 ) 关于这个

20140510 二叉树的建立 先序 后序 中序 比较

#include<stdio.h> #include<malloc.h> typedef struct node { int data; struct node *lchild,*rchild; }; node * create()//先序建立二叉树,根左右 { int x=0; node *t; printf(" input data:"); scanf("%d",&x); if(x==0) t=NULL; else { t=(no

二叉树的先序-中序-后序遍历(一)-循环----绝对白痴好记的方法

接着上一篇 二叉树的先序-中序-后序遍历(一)-递归 的讲,这篇该循环遍历了. 之前一直没有找到好的方法来循环遍历树,以前我老认为有些递归的能做的东西很难换成循环实现. 后来看了一些别人写的代码,然后又问了朋友,才发现...哦,原来这样的啊,我可以自己弄个栈来维护一下. 想到了可以弄个栈以后,至少在我认为,把递归转成循环已经是可行的了,至于怎么实现,这几天在想(因为太笨,看人家的代码总看一半就不想看),今天找到了一个好用的方法,在这里分享一下. 算法的核心是:你看二叉树的时候心里怎么想的,程序就

先序+中序和中序+后序建树

思路:先序的第一个元素和后序的最后一个元素是当前子树的根,然后遍历中序序列,找到左右子树的分界线,递归建左子树和右子树. class Solution { public: /*由于是oj,这里假设给的序列是合法的,正常情况是需要判断不合法情况的 */ TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder,int instart,int inend,int poststart,int post

二叉树先序中序非递归算法

一直想要写的 二叉树 中序 先序 后序遍历算法 当年学习DS最虚的就是这个,因为非递归算法复杂,测试数据不好弄,只能一个一个手动插入.感觉明显比图的难,虽然大家都觉得图更难..... 递归的太简单了,就不写了.关键是非递归版本. 先序: 我自己的版本: void RootPreTraverse(Node* p) { Stack S; while(S not empty) { p=S.top(); S.pop(); Show(p); if(p->right!=null) S.push(p->ri

二叉树 的先序 中序、后序遍历、层次遍历以及树状打印等操作

#include <stdio.h> #include <stdlib.h> #define MAXSIZE 50 typedef struct Node { char data; struct Node *LChild; struct Node *RChild; }BiTNode,*BiTree; typedef struct { BiTree element[MAXSIZE]; int front; int rear; }SeqQueue; /*初始化队列*/ void Ini

UVa 二叉树重建(先序+中序求后序)

题意是给出先序和中序,求出后序. 先序遍历先访问根结点,通过根结点可以在中序中把序列分为左子树部分和右子树部分,我建了一个栈,因为后序遍历最后访问根结点,所以把每次访问的根结点放入栈中.因为后序遍历先是左子树然后是右子树,所以在递归的时候就先递归右子树,然后继续递归左子树. 写完程序后有个错误,找了很久才发现,就是我原本在计算左子树个数的时候,是这样计算的,pre2=mid-pre,但是当pre>mid时,就不对了.而正确计算左子树的方法应该是下面这样的. 1 #include<iostrea

数据结构 树的创建(先序+中序)

/* 由先序遍历和中序遍历推导出树 先序遍历结果是:A D E B C F 中序遍历结果是:D E A C F B 推导流程 步骤1:由先序遍历判断出根节点是A,根据中序遍历确定根节点的左子树和右子树 因此D E是根节点的左子树,C F B是根节点的右子树 步骤2:由先序遍历确定根节点A的两个孩子节点D B 根据中序遍历确定 D为左子树 B为右子树 递归步骤1--根据中序遍历结果 E 在D的右边,则得出E是D的右子树 B是根节点 C F在B的左边 C F是左子树 根据先序遍历 C是根节点 根据中

二叉树的遍历方法之层序-先序-中序-后序遍历的简单讲解和代码示例

二叉树的基础性质及二叉树的建立参见前面两篇博文: http://blog.csdn.net/why850901938/article/details/51052936 http://blog.csdn.net/why850901938/article/details/51052156 首先为了讲解方便,我建立了如图所示的二叉树: 取名为:树A 1.何为层序遍历? 层序遍历就是按照二叉树的层次由上到下的进行遍历,每一层要求访问的顺序为从左到右: 以树A为例,层序遍历得到的结果为: 5 2 6 1