题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=104&page=show_problem&problem=489
题目类型: 数据结构, 二叉树
题目大意:
给两个组数字,都是在同一棵二叉树上的,第一组是按中序遍历(inorder)顺序输出的,第二组是按后序遍历(postorder)输出的,
根据这两组数据构建出原来的二叉树,然后计算从根结点到每个叶子结点的路径上的数字之和, 输出最小之和。
样例输入:
3 2 1 4 5 7 6
3 1 2 5 6 7 4
7 8 11 3 5 16 12 18
8 3 11 7 16 18 12 5
255
255
样例输出:
1
3
255
分析:
这题就是运用了二叉树重建, 以及遍历。
二叉树的遍历:先序遍历,中序遍历,后序遍历
只要有一个中序序列再加上另一个序列就可唯一地重建原来二叉树。
进行了二叉树重建之后,只要对这棵二叉树进行搜索, 取得各个路径之和,然后找出最小的那个和即可。
由中序遍历 分别和前序遍历,后序遍历进行建树的方法:
// 由中序和后序遍历序列进行建树, 返回根结点指针
Node * InPostCreateTree(int *mid,int *post,int len){
if(len == 0)
return NULL;
int i=len-1;
while(post[len-1] != mid[i])
--i;
Node *h=NewNode();
h->data=post[len-1];
h->left=InPostCreateTree(mid,post,i);
h->right=InPostCreateTree(mid+i+1,post+i,len-i-1);
return h;
}
// 由前序和中序遍历序列进行建树, 返回根结点的指针
Node * PreInCreateTree(int *mid,int *pre,int len) //n标识s2的长度
{
if(len==0)
return NULL;
int i = 0;
while(*mid != pre[i])
++i;
Node *h=NewNode();
h->data= *mid;
h->left = PreInCreateTree(mid+1, pre, i);
h->right = PreInCreateTree(mid+i+1, pre+i+1, len-i-1);
return h;
}
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int MAXN = 10005;
int inOrder[MAXN], postOrder[MAXN], nIndex;
class Node{
public:
int data;
Node *left;
Node *right;
};
int nodeIndex;
Node node[MAXN];
vector<int>result;
vector<Node*>pResult;
bool flag;
int ans;
inline Node* NewNode(){
node[nodeIndex].left = NULL;
node[nodeIndex].right = NULL;
return &node[nodeIndex++];
}
inline void input(){
nIndex=1;
while(getchar()!='\n')
scanf("%d", &inOrder[nIndex++]);
// 输入第二行,后序遍历
for(int i=0; i<nIndex; ++i)
scanf("%d", &postOrder[i]);
}
// 由中序和后序遍历序列进行建树, 返回根结点指针
Node * InPostCreateTree(int *mid,int *post,int len){
if(len == 0)
return NULL;
int i=len-1;
while(post[len-1] != mid[i])
--i;
Node *h=NewNode();
h->data=post[len-1];
h->left=InPostCreateTree(mid,post,i);
h->right=InPostCreateTree(mid+i+1,post+i,len-i-1);
return h;
}
void dfs(Node *root, int n){
if(!root->left && !root->right){
result.push_back(n+root->data);
pResult.push_back(root);
return ;
}
if(root->left) dfs(root->left, n+root->data);
if(root->right) dfs(root->right, n+root->data);
}
int main(){
freopen("input.txt","r",stdin);
while(~scanf("%d", &inOrder[0])){
input();
nodeIndex = 0;
Node *root = InPostCreateTree(inOrder, postOrder, nIndex);
result.clear();
pResult.clear();
dfs(root, 0);
int minPos = 0;
for(int i=1; i<result.size(); ++i)
if(result[i] < result[minPos]) minPos=i;
printf("%d\n",pResult[minPos]->data);
}
return 0;
}
—— 生命的意义,在于赋予它意义。
分享到:
相关推荐
用C++写的二叉树先序遍历、中序遍历和后序遍历非递归算法
根据先序与中序遍历结果建立二叉树 输入为: 第一行:二叉树的先序遍历结果 第二行:二叉树的中序遍历结果 例如: ①输入aa则返回的指针指向的二叉树应该就是仅有一个节点,值为a. ②输入123213则返回的指针指向...
用C++写的,包括二叉树的构建,二叉树的先序遍历、中序遍历和后序遍历非递归算法。
/*选择二叉链式存储结构作为二叉树的存储结构,设计一个程序实现二叉树的基本操作(包括建立、输出、前序遍历、中序遍历、后序遍历、求树高、统计叶子总数等) 【实验内容】 必做内容 程序的菜单功能项如下: 1----...
二叉树遍历问题 二叉树遍历问题-前序, 中序, 后序二叉树遍历问题-前序, 中序, 后序二叉树遍历问题-前序, 中序, 后序二叉树遍历问题-前序, 中序, 后序二叉树遍历问题-前序, 中序, 后序二叉树遍历问题-前序...
先根顺序建立二叉树,并对其进行线索化,实现先序遍历和中序遍历
数据结构C++二叉链表的先序遍历、中序遍历和后序遍历实现
数据结构课程实验代码,采用非递归,通过自己建立二叉树,完成中序遍历
用C语言对输入二叉树节点进行中序遍历,输出遍历顺序。包括递归实现和非递归实现两种方式。还有哈夫曼编码
二叉树已知后序和中序遍历求前序遍历,C++编写已通过编译
这段代码演示了递归和迭代方式实现二叉树的前序、中序和后序遍历。你可以根据需要,选择合适的方法进行二叉树的遍历 二叉树遍历是指按照一定的顺序访问二叉树中的所有节点。常见的二叉树遍历方式有三种:前序遍历、...
关于二叉树的创建及遍历,代码实现功能。二叉树的创建和遍历 主要完成二叉树的创建以及二叉树的先序、中序、后序遍历
完全二叉树的层序遍历-labview完全二叉树的层序遍历-labview完全二叉树的层序遍历-labview完全二叉树的层序遍历-labview完全二叉树的层序遍历-labview完全二叉树的层序遍历-labview完全二叉树的层序遍历-labview完全...
二叉树的建立及递归中序遍历,非递归中序遍历及赫夫曼编码 输入二叉树时前面要带空指针
2)对这棵二叉树进行先序遍历(采用递归算法实现)与中序遍历(采用非递归算法实现),分别输出结点的遍历序列; 2)求二叉树的深度(选做)。 这是本人所做的作业,虽然分有点多,但还是有所值的!
一个简单的课程设计,使用Java来实现二叉树的中序遍历
java编程,二叉树的中序遍历,递归实现
给出二叉树的中序遍历序列和后序遍历序列,编程还原该二叉树。 输入: 第1行为二叉树的中序遍历序列 第2行为二叉树的后序遍历序列 输出: 二叉树的按层遍历序列
二叉树的递归遍历,中序遍历,先序遍历,后序遍历,通过学习二叉树的遍历,可以让我们更紧一步掌握数据的遍历
已知二叉树的前序和中序遍历,打印后序遍历,采用二叉树的非递归算法,分享给大家~~