Pre- and Post-order Traversals(先序+后序序列,建立二叉树)

PAT甲级1119,我先在CSDN上面发布的这篇文章:https://blog.csdn.net/weixin_44385565/article/details/89737224

Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can be determined by a given pair of postorder and inorder traversal sequences, or preorder and inorder traversal sequences. However, if only the postorder and preorder traversal sequences are given, the corresponding tree may no longer be unique.

Now given a pair of postorder and preorder traversal sequences, you are supposed to output the corresponding inorder traversal sequence of the tree. If the tree is not unique, simply output any one of them.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤ 30), the total number of nodes in the binary tree. The second line gives the preorder sequence and the third line gives the postorder sequence. All the numbers in a line are separated by a space.

Output Specification:
For each test case, first printf in a line Yes if the tree is unique, or No if not. Then print in the next line the inorder traversal sequence of the corresponding binary tree. If the solution is not unique, any answer would do. It is guaranteed that at least one solution exists. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input 1:
7
1 2 3 4 6 7 5
2 6 7 4 5 3 1
Sample Output 1:
Yes
2 1 6 4 7 3 5
Sample Input 2:
4
1 2 3 4
2 4 3 1
Sample Output 2:
No
2 1 3 4
 题目大意:给定先序和后序序列,输出二叉树的中序遍历序列。若二叉树不唯一则输出任意解。

思路:下一个节点与当前节点在后序数组中紧挨着就说明二叉树不唯一,因为无法判断它是当前节点的左孩子还是右孩子。递归地建立二叉树的时候需要传递四个变量,preLeft、preRight、postLeft、postRight,也就是子树的范围即左右边界在先序和后序数组中的下标。

注意:输出二叉树后要换行!!!不然会格式错误。

 1 #include <iostream>
 2 #include <vector>
 3 #include <unordered_map>
 4 using namespace std;
 5 typedef struct node *BT;
 6 struct node {
 7     int key;
 8     BT left = NULL, right = NULL;
 9 };
10 int N;
11 bool flag = false, unique = true;
12 unordered_map <int, int> postMp;
13 vector <int> pre, post;
14 BT buildTree(int preLeft, int preRight, int postLeft, int postRight);
15 void inorder(BT tree);//中序遍历
16 int main()
17 {
18     int i;
19     scanf("%d", &N);
20     pre.resize(N);
21     post.resize(N);
22     for (i = 0; i < N; i++) {
23         scanf("%d", &pre[i]);
24     }
25     for (i = 0; i < N; i++) {
26         scanf("%d", &post[i]);
27         postMp[post[i]] = i;
28     }
29     BT tree = NULL;
30     tree = buildTree(0, N - 1, 0, N - 1);
31     printf(unique ? "Yes\n" : "No\n");
32     inorder(tree);
33     printf("\n");//结果后面要换行!!!否则就是格式错误,我还能说啥?
34 }
35 BT buildTree(int preLeft, int preRight, int postLeft, int postRight) {
36     BT tree = new node();
37     tree->key = pre[preLeft];
38     if (preLeft == preRight) {
39         return tree;
40     }
41     int next = preLeft + 1;
42     if (postMp[pre[preLeft]] - postMp[pre[next]] == 1) {
43         unique = false;
44         tree->left = buildTree(next, preRight, postLeft, postMp[pre[next]]);
45     }
46     else {
47         int leftNum = postMp[pre[next]] - postLeft;
48         tree->left = buildTree(next, next + leftNum, postLeft, postMp[pre[next]]);
49         next = next + leftNum + 1;
50         tree->right = buildTree(next, preRight, postMp[pre[preLeft + 1]] + 1, postMp[pre[next]]);
51     }
52     return tree;
53 }
54 void inorder(BT tree) {
55     if (tree) {
56         inorder(tree->left);
57         if (flag)
58             printf(" ");
59         flag = true;
60         printf("%d", tree->key);
61         inorder(tree->right);
62     }
63 }

原文地址:https://www.cnblogs.com/yinhao-ing/p/10799988.html

时间: 2024-10-12 10:18:54

Pre- and Post-order Traversals(先序+后序序列,建立二叉树)的相关文章

pat甲级1020中序后序求层序

1020 Tree Traversals (25)(25 分) 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

算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序

接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public int value; public Node left; public Node right; public Node(int data){ this.value=data; } } 一个数组的MaxTree定义如下: ◆ 数组必须没有重复元素 ◆ MaxTree是一颗二叉树,数组的每一个值对应一

算法实验-二叉树的创建和前序-中序-后序-层次 遍历

对于二叉树的创建我是利用先序遍历的序列进行创建 能够对于树节点的内容我定义为char型变量 '0'为空,即此处的节点不存在 头文件 Tree.h //链式二叉树的头文件 #pragma once #include<iostream> #include<queue> using namespace std; class BinaryTreeNode { public: char data; BinaryTreeNode *leftChild,*rightChild; BinaryTr

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

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

紫书p155 用中序后序构造二叉树

二叉树各节点权值是不相同的正整数,输入二叉树的中序后序,求到根节点权和最小的叶节点 紫书贼强,递归写的服气,慢慢理解吧 原文是建树之后用dfs搜的,我试着一边建树一边归纳最短路径 #include<bits/stdc++.h> using namespace std; const int maxv = 10010; int in[maxv], post[maxv], lch[maxv], rch[maxv];//中序,后序,左子树,右子树 int n, minnum, minsum; bool

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

二叉树的前序中序后序遍历相互求法

二叉树的前中后序遍历,他们的递归非递归.还有广度遍历,参见二叉树的前中后序遍历迭代&广度遍历和二叉树的前中后序遍历简单的递归 现在记录已知二叉树的前序中序后序遍历的两个,求另外一个.一般,这两个中一定有中序遍历. 1.已知前序和中序,求后序遍历: 前序:ABDECFG  中序:DBEAFCG 思路简单:前序的第一个节点就是根节点, 中序中找到根节点的位置,根节点之前是其左子树,之后是右子树   按此顺序,依次在左子树部分遍历,右子树部分遍历 C++ 代码: TreeNode *BinaryTre

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

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

已知先序后序构造二叉树

已知二叉树先序后序的基础上,可以构造出不唯一的二叉树集.主要思路如下: 先序遍历中刚遍历到的下一个节点是后序遍历中最后遍历的节点,所以可以将后序遍历拆分成两个子序列,从而进行递归构造. 例如 先序遍历为aebdc,后序遍历为bcdea. 首先可以确定根节点为a,在后序中找先序的下一个节点(也就是e),将原序列拆分成两部分,其左子树包含的元素有bcde,右子树为空. 接着在bcd中寻找先序中e的后一个元素即b的位置,将这个子序列又拆分成了b和cd两部分.如此递归下去就能得到一种可能的二叉树.

前序中序后序遍历非递归实现

#include<iostream> #include<vector> #include<stack> #include<string> #include<algorithm> #include<numeric> using namespace std; class node{ public: int val; node* left; node* right; node():val(0),left(NULL),right(NULL){