C++实现LeetCode(106.由中序和后序遍历建立二叉树)

[LeetCode] 106. Construct Binary Tree from Inorder and Postorder Traversal 由中序和后序遍历建立二叉树

Given inorder and postorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

For example, given

inorder = [9,3,15,20,7]
postorder = [9,15,7,20,3]

Return the following binary tree:

    3
/ \
9  20
/  \
15   7

这道题要求从中序和后序遍历的结果来重建原二叉树,我们知道中序的遍历顺序是左-根-右,后序的顺序是左-右-根,对于这种树的重建一般都是采用递归来做,可参见博主之前的一篇博客 Convert Sorted Array to Binary Search Tree。针对这道题,由于后序的顺序的最后一个肯定是根,所以原二叉树的根结点可以知道,题目中给了一个很关键的条件就是树中没有相同元素,有了这个条件就可以在中序遍历中也定位出根节点的位置,并以根节点的位置将中序遍历拆分为左右两个部分,分别对其递归调用原函数。代码如下:

class Solution {
public:
    TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
        return buildTree(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1);
    }
    TreeNode *buildTree(vector<int> &inorder, int iLeft, int iRight, vector<int> &postorder, int pLeft, int pRight) {
        if (iLeft > iRight || pLeft > pRight) return NULL;
        TreeNode *cur = new TreeNode(postorder[pRight]);
        int i = 0;
        for (i = iLeft; i < inorder.size(); ++i) {
            if (inorder[i] == cur->val) break;
        }
        cur->left = buildTree(inorder, iLeft, i - 1, postorder, pLeft, pLeft + i - iLeft - 1);
        cur->right = buildTree(inorder, i + 1, iRight, postorder, pLeft + i - iLeft, pRight - 1);
        return cur;
    }
};

上述代码中需要小心的地方就是递归是 postorder 的左右 index 很容易写错,比如 pLeft + i - iLeft - 1, 这个又长又不好记,首先我们要记住 i - iLeft 是计算 inorder 中根节点位置和左边起始点的距离,然后再加上 postorder 左边起始点然后再减1。我们可以这样分析,如果根结点就是左边起始点的话,那么拆分的话左边序列应该为空集,此时 i - iLeft 为0, pLeft + 0 - 1 < pLeft, 那么再递归调用时就会返回 NULL, 成立。如果根节点是左边起始点紧跟的一个,那么 i - iLeft 为1, pLeft + 1 - 1 = pLeft,再递归调用时还会生成一个节点,就是 pLeft 位置上的节点,为原二叉树的一个叶节点。

下面来看一个例子, 某一二叉树的中序和后序遍历分别为:

Inorder:    11  4  5  13  8  9

Postorder:  11  4  13  9  8  5  

11  4  5  13  8  9      =>          5

11  4  13  9  8  5                /  \

11  4     13   8  9      =>         5

11  4     13  9  8                  /  \

                             4   8

11       13    9        =>         5

11       13    9                    /  \

                             4   8

                            /    /     \

                           11    13    9

Github 同步地址:

https://github.com/grandyang/leetcode/issues/106

类似题目:

Construct Binary Tree from Preorder and Postorder Traversal

Construct Binary Tree from Preorder and Inorder Traversal

参考资料:

https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/discuss/758462/C%2B%2B-Detail-Explain-or-Diagram

https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/discuss/34803/Sharing-my-straightforward-recursive-solution

到此这篇关于C++实现LeetCode(106.由中序和后序遍历建立二叉树)的文章就介绍到这了,更多相关C++实现由中序和后序遍历建立二叉树内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-07-20

C++实现LeetCode(101.判断对称树)

[LeetCode] 101.Symmetric Tree 判断对称树 Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For example, this binary tree is symmetric:     1 / \ 2   2 / \   / \ 3  4 4  3 But the following is not:     1 / \ 2  

C++实现LeetCode(108.将有序数组转为二叉搜索树)

[LeetCode] 108.Convert Sorted Array to Binary Search Tree 将有序数组转为二叉搜索树 Given an array where elements are sorted in ascending order, convert it to a height balanced BST. For this problem, a height-balanced binary tree is defined as a binary tree in wh

C++实现LeetCode(99.复原二叉搜索树)

[LeetCode] 99. Recover Binary Search Tree 复原二叉搜索树 Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. Example 1: Input: [1,3,null,null,2]    1 / 3 \ 2 Output: [3,1,null,null,2]    3 / 1

C++实现LeetCode(107.二叉树层序遍历之二)

[LeetCode] 107. Binary Tree Level Order Traversal II 二叉树层序遍历之二 Given the root of a binary tree, return the bottom-up level order traversal of its nodes' values. (i.e., from left to right, level by level from leaf to root). Example 1: Input: root = [3

C++实现LeetCode(100.判断相同树)

[LeetCode] 100. Same Tree 判断相同树 Given two binary trees, write a function to check if they are the same or not. Two binary trees are considered the same if they are structurally identical and the nodes have the same value. Example 1: Input:     1     

C++实现LeetCode(102.二叉树层序遍历)

[LeetCode] 102. Binary Tree Level Order Traversal 二叉树层序遍历 Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). For example: Given binary tree {3,9,20,#,#,15,7},     3 / \ 9  20 /  \ 15 

C++实现LeetCode(145.二叉树的后序遍历)

[LeetCode] 145. Binary Tree Postorder Traversal 二叉树的后序遍历 Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3},    1 \ 2 / 3 return [3,2,1]. Note: Recursive solution is trivial, could you d

C++实现LeetCode(104.二叉树的最大深度)

[LeetCode] 104. Maximum Depth of Binary Tree 二叉树的最大深度 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. Note: A leaf is a node with no child

C++实现LeetCode(103.二叉树的之字形层序遍历)

[LeetCode] 103. Binary Tree Zigzag Level Order Traversal 二叉树的之字形层序遍历 Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). For example

PHP实现二叉树的深度优先与广度优先遍历方法

本文实例讲述了PHP实现二叉树的深度优先与广度优先遍历方法.分享给大家供大家参考.具体如下: #二叉树的广度优先遍历 #使用一个队列实现 class Node { public $data = null; public $left = null; public $right = null; } #@param $btree 二叉树根节点 function breadth_first_traverse($btree) { $traverse_data = array(); $queue = arr

Python二叉树的定义及常用遍历算法分析

本文实例讲述了Python二叉树的定义及常用遍历算法.分享给大家供大家参考,具体如下: 说起二叉树的遍历,大学里讲的是递归算法,大多数人首先想到也是递归算法.但作为一个有理想有追求的程序员.也应该学学非递归算法实现二叉树遍历.二叉树的非递归算法需要用到辅助栈,算法着实巧妙,令人脑洞大开. 以下直入主题: 定义一颗二叉树,请看官自行想象其形状, class BinNode( ): def __init__( self, val ): self.lchild = None self.rchild =

Java实现的二叉树常用操作【前序建树,前中后递归非递归遍历及层序遍历】

本文实例讲述了Java实现的二叉树常用操作.分享给大家供大家参考,具体如下: import java.util.ArrayDeque; import java.util.Queue; import java.util.Stack; //二叉树的建树,前中后 递归非递归遍历 层序遍历 //Node节点 class Node { int element; Node left; Node right; public Node() { } public Node(int element) { this.

Python二叉树的遍历操作示例【前序遍历,中序遍历,后序遍历,层序遍历】

本文实例讲述了Python二叉树的遍历操作.分享给大家供大家参考,具体如下: # coding:utf-8 """ @ encoding: utf-8 @ author: lixiang @ email: lixiang_cn@foxmail.com @ python_version: 2 @ time: 2018/4/11 0:09 @ more_info: 二叉树是有限个元素的集合,该集合或者为空.或者有一个称为根节点(root)的元素及两个互不相交的.分别被称为左子树和

PHP获取二叉树镜像的方法

本文实例讲述了PHP获取二叉树镜像的方法.分享给大家供大家参考,具体如下: 问题 操作给定的二叉树,将其变换为源二叉树的镜像. 解决思路 翻转二叉树,有递归和非递归两种方式,非递归就是使用队列. 实现代码 <?php /*class TreeNode{ var $val; var $left = NULL; var $right = NULL; function __construct($val){ $this->val = $val; } }*/ function Mirror(&$

PHP实现从上往下打印二叉树的方法

本文实例讲述了PHP实现从上往下打印二叉树的方法.分享给大家供大家参考,具体如下: 问题 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 解决思路 每层树从左到右打印,所以需要将节点的左右子树存起来,因为先进先出,所以用队列. 实现代码 /*class TreeNode{ var $val; var $left = NULL; var $right = NULL; function __construct($val){ $this->val = $val; } }*/ function

PHP实现二叉树深度优先遍历(前序、中序、后序)和广度优先遍历(层次)实例详解

本文实例讲述了PHP实现二叉树深度优先遍历(前序.中序.后序)和广度优先遍历(层次).分享给大家供大家参考,具体如下: 前言: 深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次.要特别注意的是,二叉树的深度优先遍历比较特殊,可以细分为先序遍历.中序遍历.后序遍历.具体说明如下: 前序遍历:根节点->左子树->右子树 中序遍历:左子树->根节点->右子树 后序遍历:左子树->右子树->根节点 广度优先遍历:又叫层次遍历,从上往下对每一层依

Python 二叉树的层序建立与三种遍历实现详解

前言 二叉树(Binary Tree)时数据结构中一个非常重要的结构,其具有....(此处省略好多字)....等的优良特点. 之前在刷LeetCode的时候把有关树的题目全部跳过了,(ORZ:我这种连数据结构都不会的人刷j8Leetcode啊!!!) 所以 !!!敲黑板了!!!今天我就在B站看了数据结构中关于树的内容后,又用我浅薄的Python大法来实现一些树的建立和遍历. 关于树的建立我觉得层序建立对于使用者来说最为直观,输入很好写.(好吧,我是看LeetCode中的树输入都是采用层序输入觉得

Swift算法之二叉树实现的方法示例

一.概述 二叉树的结构一般是以二叉链表的形式来存储的.二叉链表的结构类似于双向链表,二叉链表的节点也是有两个结点指针的,一个指向左子树,一个指向右子树.二叉树主要有四种遍历方式:先序遍历.中序遍历.后序遍历.层次遍历.关于二叉树的内容网上有很多,这里不再做过多的陈述. 本文将用Swift去实现二叉树的创建.四种遍历方式等.下面的实现部分内容参考了青玉伏案和唐巧两位大神相关的文章. 二.实现思路及代码 以下面二叉树为例: 先序遍历:先遍历根节点然后再遍历左子树,最后遍历右子树. 故上面先序遍历的顺

创建二叉树 二叉树如何删除节点操作教程

复制代码 代码如下: // 二叉树.cpp : 定义控制台应用程序的入口点. // /* *二叉树作业 *2012.12.1 13:55 *Made By Karld Vorn Doenitz */ #include "stdafx.h" #include<iostream> #include<string> using namespace std; class TreeNode{//建立节点类 public: char num; TreeNode *leftc