根据二叉树的先序遍历和中序遍历建立二叉树

学过数据结构的应该都知道,根据先序遍历和中序遍历可以唯一确定一颗二叉树,二叉树是递归定义的数据结构,所以一般的操作都是递归完成的,所以建树的过程也不例外,先来看这样两道题

题目一 :http://acm.hnust.cn/JudgeOnline/problem.php?id=1047

题目二 :http://acm.hnust.cn/JudgeOnline/problem.php?id=1802

其实这两道题的本质都是通过先序遍历和中序遍历建立一颗二叉树,比方说ABCD 和 BCAD这一组数据, 先序遍历的第一个字符是A,说明他是整棵树的根,以A为中心又将中序遍历序列分为了两部分,也就是根节点的左右子树,而根据中序遍历又可以把先序遍历序列再分为两部分,通过这两部分又可以确定左右子树的根,根据左右子树的根又可以确定左右子树的左右子树,这样递归下去直到序列中只剩下一个字符时就是叶子节点,这两道题都可以选择"建树"或者“不建树”直接根据序列一气呵成

题目二“建树”代码

#pragma GCC diagnostic error "-std=c++11"
#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);

using namespace std;
const int N = 26 + 5;

struct node{
    char data;
    int lchild, rchild;
    node(){ lchild = rchild = 0; }
}Tree[N];

int newnode(int x = 0){
    static int sz = 1;
    if(x) sz = 1;
    return sz++;
}

char pre[N], in[N];

void DFS(int & rt, int ps, int pt, int is, int it){
    if(rt == 0) rt = newnode();
    int pos = is;
    Tree[rt].data = pre[ps]; //根节点数据域赋值
    while(in[pos] != pre[ps]) pos++;
    if(pos != is){ //左子树不为空递归创建左子树
        DFS(Tree[rt].lchild, ps + 1, ps + pos - is, is, pos -1);
    }
    if(pos != it){ //右子树不为空递归创建右子树
        DFS(Tree[rt].rchild, ps + 1 + pos - is, pt, pos + 1, it);
    }
}

void Post_Order(int rt){
    if(rt == 0) return;
    Post_Order(Tree[rt].lchild);
    Post_Order(Tree[rt].rchild);
    printf("%c", Tree[rt].data);
    Tree[rt].lchild = Tree[rt].rchild = 0; //递归结束,左右子树清空
}

int main(){
    while(scanf("%s %s", pre, in) == 2){
        int root = 0;
        DFS(root, 0, strlen(pre) - 1, 0, strlen(in) - 1);
        Post_Order(root); puts("");
        newnode(true);
    }
    return 0;
}

题目二“不建树”代码

#pragma GCC diagnostic error "-std=c++11"
#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);

using namespace std;
const int N = 26 + 5;

char pre[N], in[N];
void DFS(int ps, int pt, int is, int it){
    int pos = is;
    while(in[pos] != pre[ps]) pos++;
    if(pos != is){
        DFS(ps + 1, ps + pos - is, is, pos - 1);
    }
    if(pos != it){
        DFS(ps + 1 + pos - is, pt, pos + 1, it);
    }
    printf("%c", pre[ps]);
}
int main(){
    while(scanf("%s %s", pre, in) == 2){
        DFS(0, strlen(pre) - 1, 0, strlen(in) - 1);
        printf("\n");
    }
    return 0;
}
时间: 2024-10-05 11:55:41

根据二叉树的先序遍历和中序遍历建立二叉树的相关文章

根据二叉树的前序遍历和中序遍历重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(

已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法

二叉树中的前序遍历是先访问根结点,再访问左子树,右子树. 中序遍历是先访问左子树,再是根结点,最后是右子树. 后序遍历是先访问左子树,再是右子树,最后是根结点. 算法思路是先根据前序遍历的第一个结点或者后序遍历的最后一个结点,查找对应在中序遍历中的位置,就可以确定左子树包含的元素和右子树包含的元素,最后通过递归来实现就可以了. 二叉树的表示形式为 //二叉树的结构表示为 class TreeNode { int val; TreeNode left; TreeNode right; TreeNo

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

问题描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 思路: 在二叉树的前序遍历序列中,第一个数字总是树的根结点的值.但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边.因此我们需要扫描中序遍历序列,才能找到根结点的值. 如下图所示,

前序遍历和中序遍历重建二叉树

对于二叉树,在此我不做过多讲解,如有不懂,请参照一下链接点击打开链接 1.在此二叉树的定义: struct BinaryTreeNode     {         BinaryTreeNode<T> *_Left;         BinaryTreeNode<T> *_Right;         T _data;     public:         BinaryTreeNode(const T& x)             :_Left(NULL)       

已知二叉树的先序遍历和中序遍历序列求后序遍历序列

package algorithm01; import java.util.Scanner; /** * 给出先序遍历和中序遍历序列求出二叉树的后续遍历序列 * @author wxisme * */ public class ToReverse { public static void main(String[] args) { Scanner scan = new Scanner(System.in); String s1, s2; while(scan.hasNext()) { s1 =

已知二叉树的前序遍历和中序遍历,如何得到它的后序遍历?

对一棵二叉树进行遍历,我们可以采取3中顺序进行遍历,分别是前序遍历.中序遍历和后序遍历.这三种方式是以访问父节点的顺序来进行命名的.假设父节点是N,左节点是L,右节点是R,那么对应的访问遍历顺序如下: 前序遍历    N->L->R 中序遍历    L->N->R 后序遍历    L->R->N /***************************************************************************************

027依据前序遍历和中序遍历,重建二叉树(keep it up)

剑指offer中题目:http://ac.jobdu.com/problem.php?pid=1385 题目描写叙述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.如果输入的前序遍历和中序遍历的结果中都不含反复的数字. 比如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列. 输入: 输入可能包括多个測试例子,对于每一个測试案例, 输入的第一行为一个整数n(1<=n<=1000):代表二叉树的节点

二叉树的遍历规则(前序遍历、后序遍历、中序遍历)

今天看了一些关于平和查找二叉树的问题,顺便也复习了一下二叉树的遍历规则,写一下学习文档. 树的遍历顺序大体分为三种:前序遍历(先根遍历.先序遍历),中序遍历(中根遍历),后序遍历(后根遍历). 如图所示二叉树: 前序遍历:前序遍历可以记为根左右,若二叉树为空,则结束返回. 前序遍历的规则: (1)访问根节点 (2)前序遍历左子树 (3)前序遍历右子树 这里需要注意:在完成第2,3步的时候,也是要按照前序遍历二叉树的规则完成. 前序遍历的输出结果:ABDECF 中序遍历:中序遍历可以记为左根右,也

二叉树重建 - (先序遍历、中序遍历、后序遍历)

对于一棵二叉树T,我们可以递归定义它的先序遍历,中序遍历,后序遍历:  1.先序遍历  ( PreOrder(T) = T的根节点 + PreOrder(T的左子树) + PreOrder(T的右子树) ) 2.中序遍历  ( InOrder(T) = InOrder(T的左子树) + T的根节点 +  InOrder(T的右子树) ) 3.后序遍历  ( PostOrder(T) = PostOrder(T的左子树) + PostOrder(T的右子树)  + T的根节点 ) 其中,加号表