剑指Offer面试题6重建二叉树(根据前序中序输出后序)
来源:互联网 发布:java jchardet 编辑:程序博客网 时间:2024/06/02 14:59
面试题6:重建二叉树。
输入二叉树的前序遍历和中序遍历结果,重建二叉树。假设输入的前序和中序结果都不含重复的数,例如:前序12473568,中序47215386,输出后序遍历结果。思路:所谓前中后序即根节点的访问顺序。前序的第一个数肯定是根节点,而根节点在中序里的中间位置,其左为左子树,右边是右子树。
假设中序的根节点左边有3个数,可知根节点的左子树有3个节点,此时这三个数的顺序即是左子树的中序。那么前序的第一个数的后边三个数肯定也是左子树,并且是该左子树的前序。
那么左右子树的前序和中序都有了,就可以递归了。下面提供了Java和C语言的实现:
Java实现:
class BinaryTreeNode{int value;BinaryTreeNode leftNode,rightNode;}public class Construct {static BinaryTreeNode rebuild(int[] preorder,int[] inorder){BinaryTreeNode root = rebuild(preorder,0,preorder.length-1,inorder,0,inorder.length-1);return root;}//参数包含子遍历,以及遍历开始和结束的位置static BinaryTreeNode rebuild(int[] preorder,int startPre,int endPre,int[] inorder,int startIn,int endIn){if( startPre > endPre || startIn > endIn || preorder.length != inorder.length){return null;}boolean haveRoot = false;//前序第一个数为根节点BinaryTreeNode root = new BinaryTreeNode();for(int i=startIn;i<=endIn;i++){//找根节点if(inorder[i] == preorder[startPre]){haveRoot = true;root.value = preorder[startPre];root.leftNode = rebuild(preorder, startPre+1, startPre+1+(i-startIn), inorder, startIn, i-1);root.rightNode = rebuild(preorder, i-startIn+startPre+1, endPre, inorder, i+1, endIn);//用数组索引比较复杂,另一种用复制数组的方法好理解。//root.leftNode = rebuild(Arrays.copyOfRange(preorder, 1, i+1), Arrays.copyOfRange(inorder, 0, i));//root.rightNode = rebuild(Arrays.copyOfRange(preorder, i+1, preorder.length), Arrays.copyOfRange(inorder, i+1,inorder.length));}}if(!haveRoot){System.out.println("没有找到根节点");return null;}return root;}//后序遍历树static void postorder(BinaryTreeNode root){if(root == null){System.out.println("根节点为空");}if(root.leftNode != null){postorder(root.leftNode);}if(root.rightNode != null){postorder(root.rightNode);}System.out.println(root.value);}public static void main(String[] args) {int[] preorder = {1,2,4,7,3,5,6,8};int[] inorder = {4,7,2,1,5,3,8,6};postorder(rebuild(preorder, inorder));}}
C语言实现:
#include<stdio.h>#include<stdlib.h>typedef struct TreeNode{int value;TreeNode* left;TreeNode* right;}BiTree,*pTree;TreeNode* constructCore(int* startpre,int* endpre,int* startin,int* endin){//参数为前序开始结束的位置,中序开始结束的位置//前序第一个数是根节点的值pTree root = (pTree)malloc(sizeof(BiTree));root->value = startpre[0];root->left = root->right = NULL;if(startpre == endpre){if(startin == endin && *startpre == *startin) return root;//重建完成else printf("错误的输入");}//在中序中找根节点的值int* rootInorder = startin;while(rootInorder <= endin && *rootInorder != root->value) ++rootInorder;if(rootInorder == endin && *rootInorder != root->value) printf("还是错误的输入");int leftLen = rootInorder - startin;int* leftEndpre = startpre + leftLen;if(leftLen >0){//构建左子树root->left = constructCore(startpre +1,leftEndpre,startin,rootInorder -1);}if(leftLen < endpre-startpre){//构建右子树,上述条件是左子树个数小于所有子树个数,所以必存在右子树root->right = constructCore(leftEndpre +1,endpre,rootInorder +1,endin);}return root;}TreeNode* construct(int* preorder,int* inorder,int length){//数组作为参数时,传入的是地址。if(preorder ==NULL || inorder == NULL || length<=0) return NULL;return constructCore(preorder,preorder + length -1,inorder,inorder + length -1);}//后序输出void postorder(pTree root){if(root == NULL) printf("后序为空");if(root->left != NULL) postorder(root->left);if(root->right != NULL) postorder(root->right);printf("%d",root->value);printf("\n");}int main(){pTree rootNode;int a[] = {1,2,4,7,3,5,6,8};//前序int b[] = {4,7,2,1,5,3,8,6};//中序rootNode = construct(a,b,8);postorder(rootNode);return 0;}
0 0
- 剑指Offer面试题6重建二叉树(根据前序中序输出后序)
- 【面试题】剑指Offer-6-根据前序和中序遍历重建二叉树
- [剑指offer] 重建二叉树,根据前中,输出后,根据中后,输出前
- 《剑指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:重建二叉树
- poj3235 Fence Repair【优先队列】
- PL/SQL developer 简介
- Jmeter中参数化的使用
- 论文推荐 负载均衡 Load Balancing
- C++头文件名 名称空间
- 剑指Offer面试题6重建二叉树(根据前序中序输出后序)
- Banana PI (香蕉派) 安装 ubuntu-core-14 最小核心的操作步骤
- 顺序表应用1:多余元素删除之移位算法
- java集合系列——List集合之ArrayList介绍(二)
- Web基础之JavaScript(二)
- 分词方法
- 如何看国外文献的方法总结
- java学习-list集合有泛型情况添加多种类型数据
- CSS属性之过渡(transition)属性