思路:

(1)需要了解前序遍历和和中序遍历的特点,前序遍历第一个元素即为根节点,然后再在中序遍历以这个根节点为界限得到宏观上的左子串和右子串,如下图

(2)又可以将截取的子串分为新的子串问题,从而可以通过迭代来解决,

(3)构建左子树:主要就是指针的运用,获取前序遍历左子串的起始地址和子串长度,中序遍历左子串起始位置和根节点位置

root->left = ConstructCore(preStart+1,leftPreOrderEnd,  inStart,rootInorder-1);

(4)同理可得右子树

root->right = ConstructCore(leftPreOrderEnd+1,preEnd,rootInorder+1,inEnd);

 #include <stdio.h>
 #include <stdlib.h>
 /*剑指offer第6个问题
 根据前序和中序遍历来重建二叉树
 */
 //定义二叉树结构
 typedef struct BiTreeNode
 {
     char data;
     struct BiTreeNode *left;
     struct BiTreeNode *right;
 }BiTreeNode;
 //重建核心函数,前序的子串起始位置和中序子串的起始位置
 BiTreeNode* ConstructCore(int *preStart,int *preEnd,int *inStart,int *inEnd);
 //重建函数 输入前序遍历和中序遍历的首位置,长度
 BiTreeNode* Construct(int *preOrder,int *inOrder,int length)
 {
     //安全性检查
     )
     {
         printf("Error input!\n");
         ;
     }
     //开始进行核心组件的迭代,
     ,
                          inOrder,inOrder+length-);
 }

 BiTreeNode* ConstructCore(int *preStart,int *preEnd,
                           int *inStart,int *inEnd)
 {
     //前序遍历的第一个元素为根节点
     ];

 //    printf("%d ",rootValue);
     //构建起始节点
     BiTreeNode* root = (BiTreeNode*)malloc(sizeof(BiTreeNode));
     root->data = rootValue;
     root->left = root->right = NULL;

     //次数遍历到最后一个元素
     if(preStart==preEnd)
     {
         if(inStart==inEnd && *preStart==*inStart)
             return root;
         ;}
     }
     /*迭代前序遍历找根节点,中序遍历*/
     //在中序遍历中找到根节点
     int *rootInorder = inStart;
     while(*rootInorder!=rootValue&&rootInorder<inEnd)
         {rootInorder++;}

 //    if(rootInorder==inEnd && *rootInorder!==rootValue)
 //    {
 //        printf("输入错误!\n");
 //        return 0;
 //    }
     //左子串的地址偏移长度
     int leftLength = rootInorder-inStart;
     //左子串的前序遍历截止地址
     int *leftPreOrderEnd = preStart+leftLength;
     //开始递归构建
     )
     {
         //构建左子树 输入为前序遍历子串的起始地址,中序遍历子串的起始地址
         root->left = ConstructCore(preStart+,leftPreOrderEnd,
                                    inStart,rootInorder-);
     }
     if(leftLength<preEnd-preStart)
     {
         //构建右子树,输入为前序遍历子串的起始地址,中序遍历子串的起始地址
         root->right = ConstructCore(leftPreOrderEnd+,preEnd,
                                     rootInorder+,inEnd);
     }
     return root;
 }

 //打印后续遍历二叉树的结果

 void lastOrderTraverse(BiTreeNode *root){
     if(root){
         lastOrderTraverse(root->left);
         lastOrderTraverse(root->right);
         printf("%d ",root->data);
     }
 }

 int main(int argc,char *argv[])
 {

     ,,,,,,,};
     ,,,,,,,};
     int length = sizeof(preorder)/sizeof(int);
     BiTreeNode *t = Construct(preorder,inorder,length);
     printf("后序遍历结果为:\n")
     lastOrderTraverse(t);

     ;
 }

剑指offer面试题6 重建二叉树(c)的更多相关文章

  1. 剑指offer面试题6 重建二叉树(java)

    注:(1)java中树的构建 (2)构建子树时可以直接利用Arrays.copyOfRange(preorder, from, to),这个方法是左开右闭的 package com.xsf.SordF ...

  2. 剑指Offer:面试题6——重建二叉树(java实现)

    问题描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不包含重复的数字. 例如: 输入:前序{1,2,4,7,3,5,6,8},中序{4,7,2,1 ...

  3. C++版 - 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解

    剑指Offer 面试题39:二叉树的深度(高度) 题目:输入一棵二叉树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二叉树 ...

  4. 剑指Offer - 九度1385 - 重建二叉树

    剑指Offer - 九度1385 - 重建二叉树2013-11-23 23:53 题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的 ...

  5. 剑指offer_面试题6_重建二叉树(分解步骤,逐个击破)

    题目:输入某二叉树的前序遍历和中序遍历的结果.请重建出该二叉树.如果输入的前序遍历和中序遍历的结果中都不含反复的数字. 比如:输入前序遍历 {1,2,4,7,3,5,6,8} 和中序遍历序列 {4,7 ...

  6. 剑指offer第二版-7.重建二叉树

    描述:输入某二叉树的前序遍历和中序遍历结果,重建该二叉树.假设前序遍历或中序遍历的结果中无重复的数字. 思路:前序遍历的第一个元素为根节点的值,据此将中序遍历数组拆分为左子树+root+右子树,前序遍 ...

  7. 剑指offer【04】- 重建二叉树(java)

    题目:重建二叉树 考点:树 题目描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6, ...

  8. 剑指offer(4)重建二叉树

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

  9. 剑指offer——面试题8:二叉树的下一个节点

    // 面试题8:二叉树的下一个结点 // 题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? // 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针. ...

随机推荐

  1. 51 nod 1610 路径计数(Moblus+dp)

    1610 路径计数 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   路径上所有边权的最大公约数定义为一条路径的值. 给定一个有向无环图.T次修改操作,每次修改一 ...

  2. poj 1873 凸包+枚举

    The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6198   Accepted: 1 ...

  3. 在 telnet 中利用HTTP协议传递GET、POST参数

    HTTP协议不仅可以用在浏览器中,还可以用在任何支持它的地方,平时用浏览器访问网站时HTTP协议内容是隐藏起来看不到的,用 telnet 就能揭开它的神秘面纱.telnet 开启方法参考文章末尾——t ...

  4. SQL优化实用方法

    SQL优化:避免索引失效 1.不使用NULL 任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的.因为只有该字段中有null值,即使创建了索引其实也是没有用 ...

  5. sprintf()、fprintf()、fscanf()的用法

    sprintf函数的用法1.该函数包含在stdio.h的头文件中. 2.sprintf和平时我们常用的printf函数的功能很相似.sprintf函数打印到字符串中,而printf函数打印输出到屏幕上 ...

  6. linux下磁盘分区详解 图文(fdisk;mkfs)

    linux分区不同于windows,linux下硬盘设备名为(IDE硬盘为hdx(x为从a-d)因为IDE硬盘最多四个,SCSI,SATA,USB硬盘为sdx(x为a-z)),硬盘主分区最多为4个,不 ...

  7. 剖析Vue原理&实现双向绑定MVVM

    转自:http://www.w3cmark.com/2016/496.html 本文能帮你做什么? 1.了解vue的双向数据绑定原理以及核心代码模块 2.缓解好奇心的同时了解如何实现双向绑定 为了便于 ...

  8. JVM内存模型及分区

    Java虚拟机在程序执行过程会把jvm的内存分为若干个不同的数据区域来管理,这些区域有自己的用途,以及创建和销毁时间. JVM内存模型如下图所示: jvm管理的内存区域包括以下几个区域:  栈区: 栈 ...

  9. 在Linux系统上获取命令帮助信息和划分man文档

    使用历史命令history 打完以后前面会有顺序号的比如1 cd2 ls3 pwd如果需要重新执行cd命令则可以执行 !3 命令 命令补全功能 比如你要执行history命令 可以打上histo+键 ...

  10. sololearn的c++学习记录_4m11d

    Function Templates Functions and classes help to make programs easier to write, safer, and more main ...