前序和中序构造树的递归实现

虽然有时候递归的效率不高,但可以化繁为简使做题的效率大大提高。是程序设计重要的一术要熟练掌握 。

就本题来说,最重要的的包括三个方面:

(1)如何设计递归体

(2)递归参数如何传递

(3)递归出口怎眼写才能使程序简化

首先,递归体的形式决定了能否较为简单的完成程序,如果细节考虑得过于繁琐,则即使用了递归程序也会写的很痛苦。因为你把本来该电脑自动完成的任务过多得交给了自己。所以,动笔之前,一定要做好顶层设计。本题设计了两个unordered_map以迅速确定子树的范围,并将其设为全局以免参数传递的麻烦。

其次,传什么,怎么传?递归体设计好后穿什么就确定了。比较大的实体可以引用的方式传递,如过程无修改再加上const。

最后,如果确定递归出口。一定要想到最简的方式,避免过分地处理细节。

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *sub(vector<int> &preorder, int pre1,int pre2,vector<int> &inorder,int in1,int in2){
        if(pre2<pre1) return nullptr; <span style="white-space:pre">	</span>//very important to assure when the recursion ends
        TreeNode *root = new TreeNode(preorder[pre1]);
        //inorder ranges
        int l1=in1, l2=in[preorder[pre1]]-1;
        int r1=l2+2, r2=in2;
        //preoder ranges
        int ll=pre1+1, lr=pre1+1+(l2-l1); // l2-l1,length of left subtree
        int rl=lr+1, rr=pre2;

        root->left=sub(preorder,ll,lr,inorder,l1,l2);
        root->right=sub(preorder,rl,rr,inorder,r1,r2);

        return root;
    }

    TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
        if(!preorder.size()||!inorder.size()) return nullptr;
        if(preorder.size()!=inorder.size()) return nullptr;
        //pre-processing
        for(int i=0 ; i< preorder.size();++i)
            pre[preorder[i]]=i;
        for(int i=0 ; i< inorder.size();++i)
            in[inorder[i]]=i;

        int n=preorder.size()-1;

        TreeNode *root=sub(preorder,0,n,inorder,0,n);

        return root;
    }

public:
    unordered_map<int,int> pre,in;

};
时间: 2024-08-11 05:35:30

前序和中序构造树的递归实现的相关文章

前序和中序构造二叉树

题目链接: 涉及知识:二叉树的遍历 分析: 二叉树的前序遍历:根节点 -> 左子树 -> 右子树 二叉树的中序遍历:左子树 -> 根节点 -> 右子树 由此可知:前序遍历中访问到的第一个元素便是根节点,通过该点便可以将中序遍历分成左右两部分,左部分的元素用来生成该二叉树的左子树,右部分用来生成二叉树的右子树. 同样,左右两部分的元素中,首先在前序遍历中出现的便是该子树的根节点,很明显符合递归的定义. 代码如下: /* * @lc app=leetcode.cn id=105 lan

C++根据前序和中序构造二叉树

#include <iostream> #include <string.h> using namespace std; template<typename Type> struct Node { Type data; Node<Type> *left; Node<Type> *right; Node(Type d = Type()):data(d),left(NULL),right(NULL){} }; template<typename

树的非递归遍历——前序、中序、后序

树的递归遍历非常简单,也是写树的遍历时最常用的写法.但是我发现自己对树的非递归遍历并不十分熟悉,所以把三种非递归遍历都写了一遍,以后看到这篇记录博客也可以帮助自己好好回想熟悉一下. Leetcode对应习题:前序,中序,后序. 相对而言,这三种非递归遍历的难度--前序 < 中序 < 后序. 对于第三种(非递归后序遍历)方法,只要稍微调整下第18~19行三个节点push的顺序,就可以实现前中后序的遍历. 树的非递归前序: 1 class Solution { 2 public: 3 vector

leetcode题解:Construct Binary Tree from Preorder and Inorder Traversal (根据前序和中序遍历构造二叉树)

题目: Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that duplicates do not exist in the tree. 说明: 1)二叉树可空 2)思路:a.根据前序遍历的特点, 知前序序列(PreSequence)的首个元素(PreSequence[0])为二叉树的根(root),  然后在中序序列(InSequence)中查找此根(

[98]验证二叉搜索树&amp;[105]从前序与中序遍历序列构造二叉树

扯闲话时间...很长一段时间没有刷题了,因为工作做得一团糟,惨遭领导怒批,心理压力大得一批导致工作时间特别长又没产出,所以刷题就搁置了... (小声BB)其实感觉领导有点刀子嘴豆腐心,一面说着"公司没义务从零培养新人,我自己也很久不带新人了",一面又给我讲了好多基础知识... 好了,言归正传,今天分享两道题,同类型的,力扣(leetcode中国)给的标签都是深度优先搜索,但是我都没想出来怎么用深度优先,所以都采用了递归. 这里提一句,曾经有位前辈和我说实际工作中递归并不常用,因为递归长

LeetCode105. 从前序与中序遍历序列构造二叉树

105. 从前序与中序遍历序列构造二叉树 描述 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 示例 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3 / 9 20 / 15 7 思路 一颗二叉树,对于前序遍历来说,其第一个元素一定是这棵树的根节点.在中序遍历中找到这个元素所在的位置,那么它的左半部分就是其左子树,右半部分就是其右子树. 重复上述过程, 通过

c++树,知道前序和中序求后序遍历

经常有面试题就是知道一棵树的前序遍历和中序遍历让你写出后序遍历,这个慢慢画是能画出来的,但是要很快的弄出来还是要懂原理. 首先说一下三种遍历:所谓的前序后序和中序都是遍历时遍历根节点的顺序.子树的话依照从做左到右的顺序,比如前序就是:中->左->右,中序就是:左->中->右. 现在前序是:ABDGCEFH 中序是:DGBAECHF 想要求后序就要把树重建出来,我们理一下思路. 1.由前序遍历的性质可以知道A必然是树的根节点 2.中序遍历中A之前的就肯定是A的左子树,A后面的就是A的

二叉树的前序、中序、后序遍历(递归、非递归)实现

本文部分来源于CSDN兰亭风雨大牛的原创.链接为http://blog.csdn.net/ns_code/article/details/12977901 二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的.二叉树有前.中.后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的).下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍

二叉树详解及二叉树的前序、中序、后序遍历(递归和非递归)

介绍二叉树之前先介绍一下树相关的概念. 树的定义:树是n(n>=0)个有限个数据的元素集合,形状像一颗倒过来的树. 树的概念: 节点:结点包含数据和指向其它节点的指针. 根节点:树第一个结点称为根节点. 结点的度:结点拥有的子节点个数. 叶节点:没有子节点的节点(度为0). 父子节点:一个节点father指向另一个节点child,则child为孩子节点,father为父亲节点 兄弟节点:具有相同父节点的节点互为兄弟节点. 节点的祖先:从根节点开始到该节点所经的所有节点都可以称为该节点的祖先. 子