Pro 6 重建二叉树

思路:

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

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

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

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

(4)同理可得右子树

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

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 /*剑指offer第6个问题
  4 根据前序和中序遍历来重建二叉树
  5 */
  6 //定义二叉树结构
  7 typedef struct BiTreeNode
  8 {
  9     char data;
 10     struct BiTreeNode *left;
 11     struct BiTreeNode *right;
 12 }BiTreeNode;
 13 //重建核心函数,前序的子串起始位置和中序子串的起始位置
 14 BiTreeNode* ConstructCore(int *preStart,int *preEnd,int *inStart,int *inEnd);
 15 //重建函数 输入前序遍历和中序遍历的首位置,长度
 16 BiTreeNode* Construct(int *preOrder,int *inOrder,int length)
 17 {
 18     //安全性检查
 19     if(preOrder==NULL||inOrder==NULL||length<0)
 20     {
 21         printf("Error input!\n");
 22         return 0;
 23     }
 24     //开始进行核心组件的迭代,
 25     return ConstructCore(preOrder,preOrder+length-1,
 26                          inOrder,inOrder+length-1);
 27 }
 28
 29 BiTreeNode* ConstructCore(int *preStart,int *preEnd,
 30                           int *inStart,int *inEnd)
 31 {
 32     //前序遍历的第一个元素为根节点
 33     int rootValue = preStart[0];
 34
 35 //    printf("%d ",rootValue);
 36     //构建起始节点
 37     BiTreeNode* root = (BiTreeNode*)malloc(sizeof(BiTreeNode));
 38     root->data = rootValue;
 39     root->left = root->right = NULL;
 40
 41
 42     //次数遍历到最后一个元素
 43     if(preStart==preEnd)
 44     {
 45         if(inStart==inEnd && *preStart==*inStart)
 46             return root;
 47         else {printf("输入错误!\n"); return 0;}
 48     }
 49     /*迭代前序遍历找根节点,中序遍历*/
 50     //在中序遍历中找到根节点
 51     int *rootInorder = inStart;
 52     while(*rootInorder!=rootValue&&rootInorder<inEnd)
 53         {rootInorder++;}
 54
 55 //    if(rootInorder==inEnd && *rootInorder!==rootValue)
 56 //    {
 57 //        printf("输入错误!\n");
 58 //        return 0;
 59 //    }
 60     //左子串的地址偏移长度
 61     int leftLength = rootInorder-inStart;
 62     //左子串的前序遍历截止地址
 63     int *leftPreOrderEnd = preStart+leftLength;
 64     //开始递归构建
 65     if(leftLength>0)
 66     {
 67         //构建左子树 输入为前序遍历子串的起始地址,中序遍历子串的起始地址
 68         root->left = ConstructCore(preStart+1,leftPreOrderEnd,
 69                                    inStart,rootInorder-1);
 70     }
 71     if(leftLength<preEnd-preStart)
 72     {
 73         //构建右子树,输入为前序遍历子串的起始地址,中序遍历子串的起始地址
 74         root->right = ConstructCore(leftPreOrderEnd+1,preEnd,
 75                                     rootInorder+1,inEnd);
 76     }
 77     return root;
 78 }
 79
 80 //打印后续遍历二叉树的结果
 81
 82 void lastOrderTraverse(BiTreeNode *root){
 83     if(root){
 84         lastOrderTraverse(root->left);
 85         lastOrderTraverse(root->right);
 86         printf("%d ",root->data);
 87     }
 88 }
 89
 90
 91
 92 int main(int argc,char *argv[])
 93 {
 94
 95     int preorder[] = {1,2,4,7,3,5,6,8};
 96     int inorder[] = {4,7,2,1,5,3,8,6};
 97     int length = sizeof(preorder)/sizeof(int);
 98     BiTreeNode *t = Construct(preorder,inorder,length);
 99     printf("后序遍历结果为:\n")
100     lastOrderTraverse(t);
101
102     return 0;
103 }
时间: 2024-10-19 14:08:14

Pro 6 重建二叉树的相关文章

Pro 6 重建二叉树(java)

注:(1)java中树的构建 (2)构建子树时可以直接利用Arrays.copyOfRange(preorder, from, to),这个方法是左开右闭的 1 package com.xsf.SordForOffer; 2 3 import java.util.Arrays; 4 5 /*剑指offer第6个问题 6 根据前序和中序遍历来重建二叉树 7 */ 8 class BinaryTreeNode { 9 public int value; 10 public BinaryTreeNod

第3章 结构之法——重建二叉树

重建二叉树 问题描述 分析与解法 用java实现的代码如下: 1 package chapter3jiegouzhifa.RebuildBinTree; 2 3 /** 4 * 重建二叉树 5 * 递归解法 6 * @author DELL 7 * 8 */ 9 public class RebuildBinTree { 10 //定义节点类 11 public static class Node{ 12 int left; //左子树位置 13 int right; //右子树位置 14 ch

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

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{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(

【编程之美】java实现重建二叉树

package com.cn.binarytree.utils; /** * @author 刘利娟 [email protected] * @version 创建时间:2014年7月20日 下午2:03:30 类说明: */ class Node { Node left; Node right; char chValue; Node(char chValue) { left = null; right = null; this.chValue = chValue; } } public cla

根据前序和中序重建二叉树

注意:1.仅根据前序和后序无法构建唯一的二叉树:2.二叉树前序遍历,第一个数字总是树的根节点的值:3.中序遍历中,根节点的值在序列的中间,左子树的值子在根节点的值的左边,右字树的值在根节点的值的右边:4.思路:递归 #include <iostream> #include <stdlib.h> using namespace std; struct Node{ int value; Node* left; Node* right; }; Node* ConstructCore(in

剑指offer 重建二叉树

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

重建二叉树与二叉树的层次遍历

数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描写叙述 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历. 输入 输入数据有多组,第一行是一个整数t (t<1000).代表有t组測试数据.每组包含两个长度小于50 的字符串,第一个字符串表示二叉树的先序遍历序列,第二个字符串表示二叉树的中序遍历序列. 输出 每组第一行输出二叉树的后序遍历序列,第二行输出二叉树的层次遍历序列 演示样例输

《剑指offer》— JavaScript(4)重建二叉树

重建二叉树 题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 实现代码 function reConstructBinaryTree(pre, vin) { if(!pre || pre.length===0){ return; } var root={ val:pre[0] }; for(var i

牛客_剑指offer_重建二叉树,再后续遍历_递归思想_分两端

   总结:    重建二叉树:其实就是根据前序和中序重建得到二叉树,得到后续,只要输出那边设置输出顺序即可 [编程题]重建二叉树 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 完整通过代码: 先新建一个二叉树的类 public class TreeNode { int val; TreeNode left