面试题6:重建二叉树
来源:互联网 发布:php 博客系统 编辑:程序博客网 时间:2024/04/30 09:01
- 题目描述:online judge
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列。
- 输入:
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行为一个整数n(1<=n<=1000):代表二叉树的节点个数。
输入的第二行包括n个整数(其中每个元素a的范围为(1<=a<=1000)):代表二叉树的前序遍历序列。
输入的第三行包括n个整数(其中每个元素a的范围为(1<=a<=1000)):代表二叉树的中序遍历序列。
- 输出:
对应每个测试案例,输出一行:
如果题目中所给的前序和中序遍历序列能构成一棵二叉树,则输出n个整数,代表二叉树的后序遍历序列,每个元素后面都有空格。
如果题目中所给的前序和中序遍历序列不能构成一棵二叉树,则输出”No”。
- 样例输入:
81 2 4 7 3 5 6 84 7 2 1 5 3 8 681 2 4 7 3 5 6 84 1 2 7 5 3 8 6
- 样例输出:
7 4 2 5 8 6 3 1 No
问题分析:
性质:二叉树的前序遍历中第一个数字总是根节点的值,中序遍历中根节点把遍历序列分为左右两颗子树。利用者两个特性我们可以重建二叉树。具体如何重建,笔者建议读者自己在草稿纸上举几个例子。弄清楚重建的过程,然后在开始编码。
java代码:
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.StreamTokenizer;public class Problem_06 {private int[] preorder;private int[] inorder;private BinaryTreeNode root;private boolean isTree = true;private StringBuilder sb;public Problem_06(int[] preorder, int[] inorder){this.preorder = preorder;this.inorder = inorder;root = construct(preorder, inorder);sb = new StringBuilder();}private BinaryTreeNode construct(int[] preorder, int[] inorder) {if(preorder.length == 0 || inorder.length == 0){isTree = false;return null;}return constructCore(0, preorder.length - 1, 0, inorder.length -1);}private BinaryTreeNode constructCore(int startPreorder, int endPreorder, int startInorder, int endInorder) {int rootValue = preorder[startPreorder];BinaryTreeNode root = new BinaryTreeNode();root.value = rootValue;if(startPreorder == endPreorder){if(startInorder == endInorder && preorder[startPreorder] == inorder[startInorder]){return root;}else{isTree = false;return null;}}//从中序遍历中找到根节点int rootInorder = startInorder;while(rootInorder <= endInorder && inorder[rootInorder] != rootValue){++rootInorder;}if(rootInorder > endInorder ||(rootInorder == endInorder && inorder[rootInorder] != rootValue)){isTree = false;return null;}int leftLength = rootInorder - startInorder;int leftPreorder = startPreorder + leftLength;if(leftLength > 0 && isTree){root.left = constructCore(startPreorder + 1, leftPreorder, startInorder, rootInorder -1 );}if(leftLength < endPreorder - startPreorder && isTree){root.right = constructCore(leftPreorder + 1, endPreorder, rootInorder + 1, endInorder);}return root;}private void postTree(BinaryTreeNode root) {if (root.left != null)postTree(root.left);if (root.right != null)postTree(root.right);sb.append(root.value+" ");}public void showTree() {if (isTree) {postTree(root);System.out.println(sb.toString());} else {System.out.println("No");}}class BinaryTreeNode{int value;BinaryTreeNode left;BinaryTreeNode right;}public static void main(String[] args) throws IOException {BufferedReader buf = new BufferedReader( new InputStreamReader(System.in));StreamTokenizer str = new StreamTokenizer(buf);while(str.nextToken() != StreamTokenizer.TT_EOF){//元素录入int length = (int)str.nval;int preorder[] = new int[length];int inorder[] = new int[length];for(int i = 0; i < preorder.length; i ++){str.nextToken();preorder[i] = (int)str.nval;}for(int i = 0; i < inorder.length; i ++){str.nextToken();inorder[i] = (int)str.nval;}new Problem_06(preorder,inorder).showTree();}}}
C++代码:
#include<iostream>#include<stdio.h>using namespace std; #define N 10000 struct BinaryTreeNode{ int m_nValue; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight;}; bool bo; BinaryTreeNode *ConstructCore(int *startPreorder, int *endPreorder, int *startInorder, int *endInorder){ int rootValue = startPreorder[0]; BinaryTreeNode *root = new BinaryTreeNode(); root->m_nValue = rootValue; root->m_pLeft = root->m_pRight = NULL; if(startPreorder == endPreorder) { if(startInorder == endInorder && *startPreorder == *startInorder) return root; else { bo = false; return NULL; } } int *rootInorder = startInorder; while(rootInorder <= endInorder && *rootInorder != rootValue) { rootInorder++; } if(rootInorder == NULL || *rootInorder != rootValue) { bo = false; return NULL; } int leftLength = rootInorder - startInorder; int *leftPreorderEnd = startPreorder + leftLength; if(leftLength > 0) { root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd, startInorder, rootInorder - 1); } if(endPreorder - startPreorder > leftLength) { root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder, rootInorder + 1, endInorder); } return root;} BinaryTreeNode *Construct(int *preorder, int *inorder, int length){ if(preorder == NULL || inorder == NULL || length <= 0) { bo = false; return NULL; } return ConstructCore(preorder, preorder + length -1, inorder, inorder + length -1);} void tailPrint(BinaryTreeNode *root){ if(root->m_pLeft != NULL) tailPrint(root->m_pLeft); if(root->m_pRight != NULL) tailPrint(root->m_pRight); printf("%d ", root->m_nValue);} int main(){ int n; while(scanf("%d", &n) != EOF) { bo = true; if(n <= 0) { printf("No\n"); return 0; } int a[N], b[N]; for(int i = 0; i < n; i++) { scanf("%d", &a[i]); } for(int j = 0; j < n; j++) { scanf("%d", &b[j]); } BinaryTreeNode *c = Construct(a, b, n); if(bo == true && c != NULL) { tailPrint(c); printf("\n"); } else printf("No\n"); } return 0;}
C代码:
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h> #define TRUE 1#define FALSE 0 typedef struct Node{ int i; struct Node* left; struct Node* right;}Node; int isNotTree=FALSE; Node* RebuildTree(int* preOrder,int* inOrder,int length){ int i=0; if(isNotTree) return NULL; Node* result=(Node*)malloc(sizeof(Node)); result->left=NULL; result->right=NULL; if(length==0) return NULL; if(length==1) { if(*preOrder!=*inOrder) { isNotTree=TRUE; return NULL; } result->i=*preOrder; return result; } for(;*preOrder!=inOrder[i];++i); result->i=*preOrder; result->left=RebuildTree(preOrder+1,inOrder,i); result->right=RebuildTree(preOrder+i+1,inOrder+i+1,length-i-1); return result;} void printTree(Node* root){ if(root!=NULL) { printTree(root->left); printTree(root->right); printf("%d ",root->i); } } int main(){ int length; int *preOrder,*inOrder; int i=0; struct Node* root=NULL; while(scanf("%d",&length)!=EOF) { preOrder=(int*)malloc(length*sizeof(int)); inOrder=(int*)malloc(length*sizeof(int)); for(i=0;i<length;++i) scanf("%d",&preOrder[i]); for(i=0;i<length;++i) scanf("%d",&inOrder[i]); root=RebuildTree(preOrder,inOrder,length); if(isNotTree==TRUE) { printf("No"); isNotTree=FALSE; } else printTree(root); printf("\n"); free(preOrder); free(inOrder); } return 0;}
测试用例:
普通二叉树(完全二叉树,不完全二叉树)
特殊二叉树(所有结点都没有左结点或右结点的树,只有一个结点的二叉树)
特殊输入测试(二叉树结点为null,输入前序和中序不匹配)
体会:
本人最先开始学的是C语言,对于指针在java中的一些类似功能不是特别熟悉,java
生成的对象不要人为管理,而C和C++需要人为销毁。所以java对于实现树和图等结构比C和C++更加容易。
- 面试题6:重建二叉树
- 重建二叉树(面试题 6)
- 面试题6:重建二叉树
- 面试题6- 重建二叉树
- 面试题6 重建二叉树
- 面试题6:重建二叉树
- 面试题6 重建二叉树
- 面试题6:重建二叉树
- 面试题6:重建二叉树
- 面试题6:重建二叉树
- 面试题6:重建二叉树
- 面试题6:重建二叉树
- 面试题6:重建二叉树
- 面试题6: 二叉树的重建
- 面试题6:重建二叉树
- 【面试题6】重建二叉树
- 面试题6:重建二叉树
- 面试题6:重建二叉树
- bzoj2018 [Usaco2009 Nov]农场技艺大赛
- string类型自带的函数
- 网络编程学习笔记(recvfrom和sendto函数)
- 图片缓存 与释放
- 黑马程序员——交通灯管理系统
- 面试题6:重建二叉树
- 2015网易游戏校园招聘笔试题 运维开发岗
- 1097卡片游戏——队列queue的应用
- 请确保此文件可访问并且是一个有效的程序集或COM组件
- Ubuntu的基本使用方法和使用技巧
- 逆序数
- .net中的接口
- (转)Java中的instanceof关键字
- 使用alpha 渐变数据切换,体验更加平滑