【面试题】剑指Offer-6-根据前序和中序遍历重建二叉树

    xiaoxiao2021-03-25  76

    题目概述

    现在有某二叉树的前序遍历和中序遍历的结果,根据此来重建二叉树

    问题分析

    这道题目旨在考察对前序和中序遍历的特点的掌握

    解题步骤

    1、前序遍历的第一个节点即为根节点

    2、根据根节点,在中序遍历中找出左子树和右子树,并统计左子树和右子树的个数

    3、递归构建左子树和右子树

    图解

    代码实现

    #pragma once #include<iostream> using namespace std; #include<assert.h> //定义二叉树节点 struct TreeNode { int pValue; TreeNode* pLeft; TreeNode* pRight; TreeNode(int data) :pValue(data) , pLeft(NULL) , pRight(NULL) {} }; typedef TreeNode Node; Node* ReConstruct(int* preorder, int* inorder, int length) { assert(preorder); assert(inorder); if (length <= 0) return NULL; //定义根节点 Node* root = new Node(*preorder); //count用来计数左子树的节点个数 //用length-count-1表示右子树的节点个数 int* pre_tmp = preorder; int* in_tmp = inorder; int leftTreeNum = 0; int protecte = length; //进行左子树个数的统计,并根据此来求出右子树的根节点pre_tmp+1 while (*in_tmp != *preorder) { leftTreeNum++; in_tmp++; pre_tmp++; protecte--; if (protecte == 1 && *in_tmp != *preorder) throw string("前序遍历和中序遍历异常"); } //划分出左子树和右子树的前序遍历和中序遍历 //并统计出左子树和右子树的节点个数 int* leftPreOrder = preorder + 1; int* rightPreOrder = pre_tmp + 1; int* leftOrder = inorder; int* rightOrder = in_tmp + 1; int rightTreeNum = length - leftTreeNum - 1; //进行递归构建左子树和右子树 root->pLeft = ReConstruct(leftPreOrder, leftOrder, leftTreeNum); root->pRight = ReConstruct(rightPreOrder, rightOrder, rightTreeNum); //返回根节点 return root; } //中序遍历 void InOrderPrint(Node* root) { if (root == NULL) return; InOrderPrint(root->pLeft); cout << root->pValue << " "; InOrderPrint(root->pRight); } void TestReConstruct() { const int M = 8; const int PreOrder[M] = { 1, 2, 4, 7, 3, 5, 6, 8 }; const int InOrder[M] = { 4, 7, 2, 1, 5, 3, 8, 6 }; int* preorder = const_cast<int*>(PreOrder); int* inorder = const_cast<int*>(InOrder); Node* root = ReConstruct(preorder, inorder, M); InOrderPrint(root); cout << endl; }

    转载请注明原文地址: https://ju.6miu.com/read-35139.html

    最新回复(0)