剑指Offer——面试题7:重建二叉树

题目:输入某二叉树的前序遍历和中序遍历结果,重建该二叉树。(假设输入的前序和中序遍历结果中都不含重复数字)

  1 #include "BinaryTree.h"
  2 #include <stdexcept>
  3 #include <iostream>
  4 #include <cstdio>
  5 #include <cstdlib>
  6
  7 BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreorder, int* startInorder, int* endInorder);
  8
  9 BinaryTreeNode* Construct(int* preorder, int* inorder, int length)
 10 {
 11     if(preorder == nullptr || inorder == nullptr || length <= 0)
 12         return nullptr;
 13
 14     return ConstructCore(preorder, preorder + length - 1,
 15         inorder, inorder + length - 1);
 16 }
 17
 18 BinaryTreeNode* ConstructCore
 19 (
 20     int* startPreorder, int* endPreorder,
 21     int* startInorder, int* endInorder
 22 )
 23 {
 24     // 前序遍历序列的第一个数字是根结点的值
 25     int rootValue = startPreorder[0];
 26     BinaryTreeNode* root = new BinaryTreeNode();
 27     root->m_nValue = rootValue;
 28     root->m_pLeft = root->m_pRight = nullptr;
 29
 30     if(startPreorder == endPreorder)
 31     {
 32         if(startInorder == endInorder && *startPreorder == *startInorder)
 33             return root;
 34         else
 35             throw -1;
 36     }
 37
 38     // 在中序遍历中找到根结点的值
 39     int* rootInorder = startInorder;
 40     while(rootInorder <= endInorder && *rootInorder != rootValue)
 41         ++ rootInorder;
 42
 43     if(rootInorder == endInorder && *rootInorder != rootValue)
 44         throw -1;
 45
 46     int leftLength = rootInorder - startInorder;
 47     int* leftPreorderEnd = startPreorder + leftLength;
 48     if(leftLength > 0)
 49     {
 50         // 构建左子树
 51         root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd,
 52             startInorder, rootInorder - 1);
 53     }
 54     if(leftLength < endPreorder - startPreorder)
 55     {
 56         // 构建右子树
 57         root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder,
 58             rootInorder + 1, endInorder);
 59     }
 60
 61     return root;
 62 }
 63
 64 // ====================测试代码====================
 65 void Test(char* testName, int* preorder, int* inorder, int length)
 66 {
 67     if(testName != nullptr)
 68         printf("%s begins:\n", testName);
 69
 70     printf("The preorder sequence is: ");
 71     for(int i = 0; i < length; ++ i)
 72         printf("%d ", preorder[i]);
 73     printf("\n");
 74
 75     printf("The inorder sequence is: ");
 76     for(int i = 0; i < length; ++ i)
 77         printf("%d ", inorder[i]);
 78     printf("\n");
 79
 80     try
 81     {
 82         BinaryTreeNode* root = Construct(preorder, inorder, length);
 83         PrintTree(root);
 84         DestroyTree(root);
 85     }
 86     catch(int d)
 87     {
 88         printf("Invalid Input.\n");
 89     }
 90 }
 91
 92 // 普通二叉树
 93 //              1
 94 //           /      95 //          2       3
 96 //         /       /  97 //        4       5   6
 98 //         \         /
 99 //          7       8
100 void Test1()
101 {
102     const int length = 8;
103     int preorder[length] = {1, 2, 4, 7, 3, 5, 6, 8};
104     int inorder[length] = {4, 7, 2, 1, 5, 3, 8, 6};
105
106     Test("Test1", preorder, inorder, length);
107 }
108
109 // 所有结点都没有右子结点
110 //            1
111 //           /
112 //          2
113 //         /
114 //        3
115 //       /
116 //      4
117 //     /
118 //    5
119 void Test2()
120 {
121     const int length = 5;
122     int preorder[length] = {1, 2, 3, 4, 5};
123     int inorder[length] = {5, 4, 3, 2, 1};
124
125     Test("Test2", preorder, inorder, length);
126 }
127
128 // 所有结点都没有左子结点
129 //            1
130 //             \
131 //              2
132 //               \
133 //                3
134 //                 135 //                  4
136 //                   137 //                    5
138 void Test3()
139 {
140     const int length = 5;
141     int preorder[length] = {1, 2, 3, 4, 5};
142     int inorder[length] = {1, 2, 3, 4, 5};
143
144     Test("Test3", preorder, inorder, length);
145 }
146
147 // 树中只有一个结点
148 void Test4()
149 {
150     const int length = 1;
151     int preorder[length] = {1};
152     int inorder[length] = {1};
153
154     Test("Test4", preorder, inorder, length);
155 }
156
157 // 完全二叉树
158 //              1
159 //           /     160 //          2       3
161 //         / \     / 162 //        4   5   6   7
163 void Test5()
164 {
165     const int length = 7;
166     int preorder[length] = {1, 2, 4, 5, 3, 6, 7};
167     int inorder[length] = {4, 2, 5, 1, 6, 3, 7};
168
169     Test("Test5", preorder, inorder, length);
170 }
171
172 // 输入空指针
173 void Test6()
174 {
175     Test("Test6", nullptr, nullptr, 0);
176 }
177
178 // 输入的两个序列不匹配
179 void Test7()
180 {
181     const int length = 7;
182     int preorder[length] = {1, 2, 4, 5, 3, 6, 7};
183     int inorder[length] = {4, 2, 8, 1, 6, 3, 7};
184     Test("Test7: for unmatched input", preorder, inorder, length);
185 }
186
187 int main(int argc, char* argv[])
188 {
189     Test1();
190     Test2();
191     Test3();
192     Test4();
193     Test5();
194     Test6();
195     Test7();
196     return 0;
197 }

             

  • 构建二叉树的两个函数:Construct()、ConstructCore()
  • Construct()面向输入数据(用户),ConstructCore()面向处理数据(程序)
  • 通过Construct()调用ConstructCore(),对用户隐藏了具体实现

BinaryTree.cpp

 1 #include <cstdio>
 2 #include "BinaryTree.h"
 3
 4 BinaryTreeNode* CreateBinaryTreeNode(int value)
 5 {
 6     BinaryTreeNode* pNode = new BinaryTreeNode();
 7     pNode->m_nValue = value;
 8     pNode->m_pLeft = nullptr;
 9     pNode->m_pRight = nullptr;
10
11     return pNode;
12 }
13
14 void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight)
15 {
16     if(pParent != nullptr)
17     {
18         pParent->m_pLeft = pLeft;
19         pParent->m_pRight = pRight;
20     }
21 }
22
23 void PrintTreeNode(const BinaryTreeNode* pNode)
24 {
25     if(pNode != nullptr)
26     {
27         printf("value of this node is: %d\n", pNode->m_nValue);
28
29         if(pNode->m_pLeft != nullptr)
30             printf("value of its left child is: %d.\n", pNode->m_pLeft->m_nValue);
31         else
32             printf("left child is nullptr.\n");
33
34         if(pNode->m_pRight != nullptr)
35             printf("value of its right child is: %d.\n", pNode->m_pRight->m_nValue);
36         else
37             printf("right child is nullptr.\n");
38     }
39     else
40     {
41         printf("this node is nullptr.\n");
42     }
43
44     printf("\n");
45 }
46
47 void PrintTree(const BinaryTreeNode* pRoot)
48 {
49     PrintTreeNode(pRoot);
50
51     if(pRoot != nullptr)
52     {
53         if(pRoot->m_pLeft != nullptr)
54             PrintTree(pRoot->m_pLeft);
55
56         if(pRoot->m_pRight != nullptr)
57             PrintTree(pRoot->m_pRight);
58     }
59 }
60
61 void DestroyTree(BinaryTreeNode* pRoot)
62 {
63     if(pRoot != nullptr)
64     {
65         BinaryTreeNode* pLeft = pRoot->m_pLeft;
66         BinaryTreeNode* pRight = pRoot->m_pRight;
67
68         delete pRoot;
69         pRoot = nullptr;
70
71         DestroyTree(pLeft);
72         DestroyTree(pRight);
73     }
74 }

BinaryTree.h

 1 struct BinaryTreeNode
 2 {
 3     int                    m_nValue;
 4     BinaryTreeNode*        m_pLeft;
 5     BinaryTreeNode*        m_pRight;
 6 };
 7
 8 BinaryTreeNode* CreateBinaryTreeNode(int value);
 9 void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight);
10 void PrintTreeNode(const BinaryTreeNode* pNode);
11 void PrintTree(const BinaryTreeNode* pRoot);
12 void DestroyTree(BinaryTreeNode* pRoot);

原文地址:https://www.cnblogs.com/cxc1357/p/12014209.html

时间: 2024-07-30 21:23:36

剑指Offer——面试题7:重建二叉树的相关文章

剑指offer 面试题7.重建二叉树

0.题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果都不包含重复的数字. 1.解法 1)由前序遍历的第一个节点可以得到该树的根节点R. 2)在中序遍历中找到该根节点R,R节点可将中序遍历的序列分成左子树和右子树. 3)将左子树和右子树作为新的子树并重复1) 原文地址:https://www.cnblogs.com/Justdocument/p/12394777.html

【剑指offer】Q6:重建二叉树

class BTNode: def __init__(self, val): self.left = None self.right = None self.val = val ''' @ construct tree by inorder & preorder ''' def constructByInPre(inorder, instart, inend, preorder, prestart, preend): if inend < instart or preend < pre

[ 剑指offer ] 面试题8:二叉树的下一个节点

题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 解题思路 1.找到所有的可能情况并归纳,写的代码需要把这些情况都覆盖到. 2.具体情况详见书本# -*- coding:utf-8 -*- # class TreeLinkNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None # self

剑指offer系列源码-重建二叉树

oj地址 </pre><p><pre name="code" class="html">题目1385:重建二叉树 时间限制:1 秒内存限制:32 兆特殊判题:否提交:3609解决:1091 题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输

剑指offer(三十三)之重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 代码: <span style="font-size:18px;">/** * Definition for binary tree * public class TreeNode { * int val; * TreeNode

【剑指Offer】4、重建二叉树

??题目描述: ??输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回根结点. ??解题思路: ??树的遍历有三种:分别是前序遍历.中序遍历.后序遍历.本题是根据前序和中序遍历序列重建二叉树,我们可以通过一个具体的实例来发现规律,不难发现:前序遍历序列的第一个数字就是树的根结点.在中序遍历序列中,可以扫描找到根结点

【剑指Offer】04、重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 题解:递归 1 public static TreeNode reConstructBinaryTree(int[] pre,int[] in) { 2 if(pre.length==0||in.length==0){ 3 return null; 4

【剑指offer】7、重建二叉树

题目 给出二叉树的前序遍历与中序遍历结果,重建该二叉树. 思路 由于前序遍历的第一个数字是根节点,将中序遍历分为左右子树两个部分.接下来就递归,将左子树和右子树的序列分离出来,然后调用递归函数. TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { int length = pre.size() - 1; TreeNode* root = ConstructCore(pre, 0, length , v

二叉树层次遍历(剑指Offer面试题32:从上到下打印二叉树)

图1所示为二叉树的层次遍历,即按照箭头所指方向,按照1.2.3的层次顺序,对二叉树每个节点进行访问 (此图反映的是自左至右的层次遍历,自右至左的方式类似). 要进行层次遍历,需要建立一个队列.先将二叉树头节点入队列,然后出队列,访问该节点, 如果它有左子树,则将左子树的根结点入队:如果它有右子树,则将右子树的根结点入队.然后出队列,对出队节点访问, 如此反复直到队列为空为止. 1 import java.util.*; 2 class TreeNode 3 { 4 int val; 5 Tree

【剑指Offer面试题】二维数组中的查找

下决心AC所有剑指offer面试题. 九度OJ面试题地址:http://ac.jobdu.com/hhtproblems.php 书籍:何海涛--<剑指Offer:名企面试官精讲典型编程题> 对于面试题,面试官往往更希望我们能提出优化方法,这样更能体现我们的思维能力以及传说中的"内功".所以做剑指offer要着重训练这方面,多总结多细究,总是有好处的.加油~ 二维数组中的查找 时间限制:1 秒内存限制:32 兆 特殊判题:否提交:19005解决:3642 题目描述: 在一个