[无需建树]已知前序或后序和中序遍历结果,输出前序或后序或层次遍历的方法汇总

最近刷PAT老是碰到这种憨批题目,这种题目在算法面试中也是常客了,主要分为4类

  • 已知前序 中序,求后序
  • 已知前序 中序,求层次
  • 已知后序 中序,求前序
  • 已知前序 中序,求层次

而这四种题目如果要做出来的话,通通不需要建树,因为建树也是按照一定的递归顺序来的,就算是层次遍历,也可以在递归途中保存一些信息来获得.

我们先给出一颗二叉树

可以得到以下信息

  • 前序:4,1,3,2,6,5,7
  • 中序:1,2,3,4,5,6,7
  • 后序:2,3,1,5,7,6,4
  • 层次:4,1,6,3,5,7,2

前序&中序-->后序

利用递归,前序遍历的第一个永远是根,root表示根在前序数组中的index,left表示子树的左边界,right表示子树的右边界.第一次调用pos(0,0,6),然后在中序数组中找到分界点4,index=3.所以子树被分为了[left,index-1]和[index+1,right],也就是[0,2]和[4,6].root+1就是左子树根的下标,root+1+左子树数目\((i+1-left)\)就是右子树根的下标,然后递归即可.注意先递归左子树,再右子树,最后再输出当前节点.

index 0 1 2 3 4 5 6
前序 4 1 3 2 6 5 7
中序 1 2 3 4 5 6 7
int pre[]={4,1,3,2,6,5,7};
int mid[]={1,2,3,4,5,6,7};
void pos(int root,int left,int right)
{
    //相等的话还是能输出一个,所以left>right再终结
    if(left>right)return;
    int i=left;
    while(i<right&&mid[i]!=pre[root])i++;
    pos(root+1,left,i-1);
    pos(root+(i+1-left),i+1,right);
    printf("%d ",pre[root]);
}
int main()
{
    pos(0,0,6);
}

前序&中序-->层次

层次就是用来白给的,可以记录某个节点再完全二叉树的id号,然后排序输出即可得到,对于一个index的节点(index从0开始),左儿子为(\(index*2+1\)),右儿子为(\(index*2+2\)),然后扔进优先队列即可

#include <iostream>
#include<bits/stdc++.h>
#define each(a,b,c) for(int a=b;a<=c;a++)
#define de(x) cout<<#x<<" "<<(x)<<endl
using namespace std;

const int maxn=500+5;
const int inf=0x3f3f3f3f;

int pre[]={4,1,3,2,6,5,7};
int mid[]={1,2,3,4,5,6,7};

struct node
{
    int value;
    int index;
    node(int v,int i):value(v),index(i){}
    bool operator<(const node&r)const
    {
        return index>r.index;
    }
};
priority_queue<node>Q;
void pos(int root,int left,int right,int index)
{
    //相等的话还是能输出一个,所以left>right再终结
    //de(pre[root]);

    if(left>right)return;
    int i=left;
    while(i<right&&mid[i]!=pre[root])i++;
    //de(pre[root]);
    //de(index);
    Q.push(node(pre[root],index));
    pos(root+1,left,i-1,index*2+1);
    pos(root+(i+1-left),i+1,right,index*2+2);
    printf("%d ",pre[root]);
}
int main()
{
    pos(0,0,6,0);
    cout<<endl;
    while(!Q.empty())
    {
        cout<<Q.top().value<<" ";
        Q.pop();
    }
}

后序&中序-->前序/层次

原理相同,修改一下递归下标,输出顺序和数组名字就可以了.

#include <iostream>
#include<bits/stdc++.h>
#define each(a,b,c) for(int a=b;a<=c;a++)
#define de(x) cout<<#x<<" "<<(x)<<endl
using namespace std;

const int maxn=500+5;
const int inf=0x3f3f3f3f;

int pos[]={2,3,1,5,7,6,4};
int mid[]={1,2,3,4,5,6,7};

struct node
{
    int value;
    int index;
    node(int v,int i):value(v),index(i){}
    bool operator<(const node&r)const
    {
        return index>r.index;
    }
};
priority_queue<node>Q;
void pre(int root,int left,int right,int index)
{
    //相等的话还是能输出一个,所以left>right再终结
    //de(pre[root]);

    if(left>right)return;
    int i=left;
    while(i<right&&mid[i]!=pos[root])i++;
    //de(pre[root]);
    //de(index);
    Q.push(node(pos[root],index));
    printf("%d ",pos[root]);
    pre(root-(right+1-i),left,i-1,index*2+1);
    pre(root-1,i+1,right,index*2+2);

}
int main()
{
    pre(6,0,6,0);
    cout<<endl;
    while(!Q.empty())
    {
        cout<<Q.top().value<<" ";
        Q.pop();
    }
}

原文地址:https://www.cnblogs.com/Tony100K/p/11766166.html

时间: 2024-10-15 05:04:53

[无需建树]已知前序或后序和中序遍历结果,输出前序或后序或层次遍历的方法汇总的相关文章

给定二叉树的先序遍历和中序遍历,输出它的后序遍历序列

这里没再用到先申请大Node数组的方法了,想练练写动态内存分配和释放的,一次OK了,也没怎么出错啊,开心~ 方法二 - Code: //给出一个二叉树的先序遍历和中序遍历,输出它的后序遍历 //直接构造的方法白书已给出.这里是先递归构造二叉树,然后进行后序遍历. #include<stdio.h> #include<string.h> #include<stdlib.h> #define MAXN 1000 typedef struct node { char data

数据结构:树的BFS,树的层次遍历! 按先序遍历创建一棵树,然后以层次遍历输出。

按先序遍历创建一棵树,以层次遍历输出 样例输入 A B # D # # C E # # F # # 样例输出 LevelOrder: A B C D E F 代码: #include <iostream> #include <queue> using namespace std; struct node { //表示一个树上的节点 char ch; node *left, *right; }; node* creat() { //以递归的方式构造一棵二叉树 node *root =

PAT A1020——已知后序中序遍历求层序遍历

1020 Tree Traversals Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, you are supposed to output the level order traversal sequence of the corresponding binary tree. Input

HLG2040二叉树遍历已知前中,求后

二叉树的遍历 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 60(34 users) Total Accepted: 34(30 users) Rating: Special Judge: No Description 给出一棵二叉树的中序和前序遍历,输出它的后序遍历. Input 本题有多组数据,输入处理到文件结束. 每组数据的第一行包括一个整数n,表示这棵二叉树一共有n个节点. 接下来的一行每行包括n个整数,表示这棵树的中序遍

二叉树遍历,深度有限遍历,广度优先遍历,前序中序后续优先遍历,层次遍历

首先明白两个概念: 1. 深度遍历包括前中后序遍历三种: 2. 广度优先遍历就是层次遍历. PS: 前中后序遍历,如果使用递归遍历,都很简单易理解: 如果使用非递归方式,首先想到的就应该是使用栈结构来控制整个过程,因为递归也是利用栈来实现的: 前中后序遍历的非递归方式中,后序遍历的非递归方式相比较而言,略复杂. 直接上代码: #include "stdlib.h" #include <iostream> #include <stack> #include <

二叉树遍历算法——包含递归前、中、后序和层次,非递归前、中、后序和层次遍历共八种

首先,要感谢网上的参考资料. http://mengliao.blog.51cto.com/876134/1178079(作者:BlackAlpha) http://blog.csdn.net/fzh1900/article/details/14056735(作者:_云淡风轻) http://blog.csdn.net/stpeace/article/details/8138458(作者:stpeace) 二叉树是使用的比较广泛的一种数据结构,这里我写了二叉树的相关操作,包括初始化.新建.以及遍

树的前中后序遍历和层次遍历

遍历规则 前序遍历:根结点 ---> 左子树 ---> 右子树 中序遍历:左子树---> 根结点 ---> 右子树 后序遍历:左子树 ---> 右子树 ---> 根结点 层次遍历:只需按层次遍历即可 注: 1.前序.中序.后序属于深度优先遍历(使用递归较为方便),层次遍历为广度优先遍历(一般实现需要借助其他数据结构的支撑,如下面的队列等). 2.中序遍历有个小技巧:对于给定的树,可以画垂线,从左到右即为中序遍历的次序. 代码实现 #include <iostrea

OpenCV使用二维特征点(Features2D)和单映射(Homography)寻找已知物体

使用二维特征点(Features2D)和单映射(Homography)寻找已知物体 目标 在本教程中我们将涉及以下内容: 使用函数 findHomography 寻找匹配上的关键点的变换. 使用函数 perspectiveTransform 来映射点. 理论 代码 这个教程的源代码如下所示.你还可以从 以下链接下载到源代码 #include <stdio.h> #include <iostream> #include "opencv2/core/core.hpp"

递归非递归的二叉树遍历(递归前中后,非递归前中后,层次遍历,凹入打印法等)

由于所有的递归算法都可以借助于堆栈转换成循环结构的非递归算法.方法一:形式化模拟转换.方法二:根据要求解问题的特点设计借助于堆栈的循环结构算法.而此次正好是利用第二种按方法求解. 1.1非递归前序遍历: 首先利用下图来设计非递归前序遍历算法思想: 堆栈结构体如下: #define size 100 typedef struct { DataType data[size]; int tag[100]; //这个是在非递归后序中用到 int top : }SeqStack : (1)初始化设置一个堆