剑指Offer面试题6[重建二叉树]
来源:互联网 发布:软件拉新方案 编辑:程序博客网 时间:2024/06/05 00:38
1.题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
2. 相关知识:
2.1 树的相关概念:
结点拥有的子树的个数成为结点的度,度为0的结点称为叶子或者终端结点,树中结点的最大层次称为树的深度。
2.2 二叉树相关概念:
二叉树的每个结点最多只有两颗子树,二叉树的第
二叉树共有三种遍历方式,为笔试面试考点的重中之重,以下图为例。
- 前序遍历(根-左-右):10-6-4-8-14-12-16
- 中序遍历(左-根-右):4-6-8-10-12-14-16
- 后序遍历(左-右-根):4-8-6-12-16-14-10
另外,还有一种宽度优先遍历:从上到下,从左到右,如上图所示为:10-6-14-4-8-12-16
2.3 特殊的二叉树:
- 二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree):左子结点总是小于或等于根结点,右子节点总是大于或等于根结点。上图的例子便是二叉搜索树。二叉搜索树中查找某结点的时间为
O(log2(n)) 。 - 堆:分为最大堆(根节点最大)和最小堆(根结点最小)
- 平衡二叉树:左子树和右子树的深度只差绝对值不超过1.
- 红黑树:
- 哈夫曼树:给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
3. 解答思路:
根据前序遍历、中序遍历的特点,采用递归的方法分别重建出左右子树
4. 代码实现:
C语言版本
#include "stdafx.h" #include <vector> #include <stack> #include <iostream> #include <stdio.h> #include <stdlib.h> using namespace std; //树的结构体struct BinaryTreeNode { int value; BinaryTreeNode* pLeft; BinaryTreeNode* pRight; };void PrintTreeNode(BinaryTreeNode* pNode){ if(pNode != NULL) { printf("value of this node is: %d\n", pNode->value); if(pNode->pLeft != NULL) printf("value of its left child is: %d.\n", pNode->pLeft->value); else printf("left child is null.\n"); if(pNode->pRight != NULL) printf("value of its right child is: %d.\n", pNode->pRight->value); else printf("right child is null.\n"); } else { printf("this node is null.\n"); } printf("\n");}void PrintTree(BinaryTreeNode* pRoot){ PrintTreeNode(pRoot); if(pRoot != NULL) { if(pRoot->pLeft != NULL) PrintTree(pRoot->pLeft); if(pRoot->pRight != NULL) PrintTree(pRoot->pRight); }}//递归BinaryTreeNode* reConstructBinaryTree(int* startPreOdrer, int* endPreOrder, int* startInOrder, int* endInOrder){ //前序遍历 int rootValue = *startPreOdrer; BinaryTreeNode* treeNode = (BinaryTreeNode*)malloc(sizeof(BinaryTreeNode)); treeNode->value = rootValue; treeNode->pLeft = NULL; treeNode->pRight = NULL; if (startPreOdrer == endPreOrder) { if (startInOrder == endInOrder && *startPreOdrer == *startInOrder) return treeNode; //递归出口 } //中序遍历 int* rootInOrder = startInOrder; while (rootInOrder <= endInOrder && *rootInOrder != rootValue) { rootInOrder++; } int leftLength = rootInOrder - startInOrder; int *leftPreOrderEnd = startPreOdrer + leftLength; if (leftLength > 0)//重建左子树 { treeNode->pLeft = reConstructBinaryTree(startPreOdrer + 1, leftPreOrderEnd, startInOrder, rootInOrder - 1); } if (endPreOrder - startPreOdrer - leftLength > 0)//重建右子树 { treeNode->pRight = reConstructBinaryTree(leftPreOrderEnd + 1, endPreOrder, rootInOrder + 1, endInOrder); } return treeNode;}BinaryTreeNode* reConstruct(int* preOrder, int*inOrder, int length){ if (preOrder == NULL || inOrder == NULL || length < 0) return NULL; return reConstructBinaryTree(preOrder, preOrder + length - 1, inOrder, inOrder + length - 1);}int _tmain(int argc, _TCHAR* argv[]){ const int length = 8; int preorder[length] = {1, 2, 4, 7, 3, 5, 6, 8}; int inorder[length] = {4, 7, 2, 1, 5, 3, 8, 6}; BinaryTreeNode* root= reConstruct(preorder, inorder, length); PrintTree(root); system("pause"); return 0;}
C++语言版本
// ex06_cpp.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <vector> #include <stack> #include <iostream> #include <stdio.h> #include <stdlib.h> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {}};class Solution {public: TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { int length = pre.size(); if(length == 0)//递归出口 return NULL; int rootValue = pre[0];//前序遍历root结点 TreeNode *node = new TreeNode(rootValue); int p = 0;//指向中序遍历root结点 for(; p < length; p++) { if (vin[p] == rootValue) break; } //先序左子树、右子树,中序左子树、右子树 vector<int> pre_left(pre.begin()+1, pre.begin()+p+1); vector<int> pre_right(pre.begin()+p+1, pre.end()); vector<int> in_left(vin.begin(), vin.begin()+p); vector<int> in_right(vin.begin()+p+1, vin.end()); node->left = reConstructBinaryTree(pre_left, in_left); node->right = reConstructBinaryTree(pre_right, in_right); return node; }};int _tmain(int argc, _TCHAR* argv[]){ const int length = 8; int preorder[8] = { 1, 2, 4, 7, 3, 5, 6, 8 }; int inorder[8] = { 4, 7, 2, 1, 5, 3, 8, 6 }; vector<int> pre_vec(preorder,preorder+length); vector<int> in_vec(inorder,inorder+length); Solution s; TreeNode* node = s.reConstructBinaryTree(pre_vec,in_vec); return 0;}
阅读全文
0 0
- 《剑指Offer》面试题-重建二叉树
- 剑指offer--面试题6: 重建二叉树(树)
- 剑指offer-->面试题6 重建二叉树
- 【剑指offer】面试题6:重建二叉树
- 《剑指offer》面试题6:重建二叉树
- 剑指offer 面试题6 重建二叉树
- 剑指Offer:面试题6 重建二叉树
- 《剑指offer》面试题6:重建二叉树
- 《剑指offer》面试题6重建二叉树
- 剑指offer面试题6--重建二叉树
- 理解《剑指Offer》之面试题6 重建二叉树
- 剑指offer 面试题6 重建二叉树
- 剑指offer面试题6 重建二叉树(c)
- 剑指offer面试题6 重建二叉树(java)
- 《剑指Offer》面试题6:重建二叉树
- 剑指offer--面试题6:重建二叉树--Java实现
- 【剑指Offer学习】【面试题6 :重建二叉树】
- 《剑指Offer》学习笔记--面试题6:重建二叉树
- android线程管理四(Looper,Handler,Message)
- 第5章 CloudStack区域的创建与配置
- 环信自定义消息实现方式
- Watchdog机制以及问题分析
- 1005. 继续(3n+1)猜想 (25)
- 剑指Offer面试题6[重建二叉树]
- 在Android M及更高版本中使用 Settings.System 抛出异常"You cannot keep your settings in the secure settings. "
- android设备 uvc摄像头 相关
- Tiled结合Unity实现瓦片地图——Unity实战篇
- 已解决:Opencv获取视频,播放窗口一闪而过
- 中企动力与港田高分子同行 创建营销型企业云平台
- python学习过程对self的理解
- 23种设计模式(6):模版方法模式
- 剑指offer题21