需要存储数据进去,可以使用一个结构体会更加的方便
顺便提一嘴,头文件是
#include
#include
struct node {
int left, right;
};
node tree[MAXN];
其中 left 和 right 分别代表其左右子节点,读入也十分方便,
_for (i,1,n) cin>>tree[i].left>>tree[i].right
这里介绍一个for循环的简化写法,非常方便。
在头文件下放入新的定义
#define _for(i,a,b) for(int i=(a);i<=(b);i++)
以后便可以直接简写。
记得将第一项标记出来,就是头根标记出来,作为递归的起点
正所谓擒贼先擒王
可以先确定跟,然后再顺次输入左右树
cin>>t;
cin>>tree[t].left>>tree[t].right;
我们需要从根节点出发,先递归遍历该节点的左节点,再递归遍历该节点的右节点
dfs(tree[i].left,deep+1)
dfs(tree[i].right,deep+1)
中间可以加入其他操作,当到达叶子节点时就应该结束操作,直接return。
所以整个应该是
void dfs(int di,int deep)
{
if (id==0) return ;//这个还可以是其他的限制条件,主要是底部什么时候是空,看题目
...//其他操作
cout<
使用递归遍历它会自动遍历至底部
这个先中后其实就是根所在的位置
先序排列 根左右
中序排列 左根右
后序排列 左右根
不难发现,先序排列的根一定在开头,后序排列的根一定在末尾,而中序排列的根会出现在中间
如此,当我们已知先序或后序和中序后,我们便可以求出未知的那项
具体方法是使用递归
1,先找出根(先序找开头,后序找结尾)
在这里可以用string函数来找开头和结尾,#.size()即可知道字符串长度,注意-1,因为是从0开始计数。
2,找到根所在的位置,将中序一分为二
这里可以使用substr(开头,结尾)也是非常好用
3, 先序就先右边再左边,因为先序是往右边开始
后序就先左边再右边,因为后序要往左开始
void dfs(string in ,string after)
{
if(in.size()>0)
{
ch = after[after.size()-1];
cout<
void dfs(string in ,string after)
{
if(in.size()>0)
{
ch = after[0];
cout<
这不同于知道根和各各子节点的位置,是需要通过中序遍历和后序遍历才可以构建的二叉树,方法和已知中序和后序求先序很相似,但也有不同
int create_tree(int inorder_start,int postorder_start,int length) { if(length<=0){ return 0; } int root = postorder[postorder_start+length-1]; int count =0; while(inorder[inorder_start+count]!=root){ count ++; } T_left[root]=create_tree(inorder_start,postorder_start,count); T_right[root]=create_tree(inorder_start+count+1,postorder_start+count,length-1-count); return root; }
如果需要求每个子节点的最小和,存在多路径最小的情况下,应该选择终端叶子节点上具有最小值的那条路径,且输出那个最小值的终端叶子
void findmin(int root,int sum)
{
sum+=root;
if(T_left[root]==0&&T_right[root]==0){
if(sum0) findmin(T_left[root],sum);
if(T_right[root]>0) findmin(T_right[root],sum);
}
写的非常清楚明白了
输入一个二叉树的中序和后序遍历,请你输出一个叶子节点,该叶子节点到根的数值总和最小,且这个叶子是编号最小的那个。
输入:
您的程序将从输入文件中读取两行(直到文件结尾)。第一行是树的中序遍历值序列,第二行是树的后序遍历值序列。所有值将不同,大于零且小于或等于10000.二叉树的节1<=N<=10000。
输出:
对于每个树描述,您应该输出最小值路径的叶节点的值。存在多路径最小的情况下,您应该选择终端叶子节点上具有最小值的那条路径,且输出那个最小值的终端叶子。
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
#include
using namespace std;
const int maxn = 10010;
int postorder[maxn],inorder[maxn],T_left[maxn],T_right[maxn],n,x;
int min_sum,min_root,sum,root;
string str,str2;
bool readline(int *arr)
{
if(!getline(cin,str))
{
return false;
}
stringstream s(str);
n=0,x;
while (s>>x){
arr[n++]=x;
}
return true;
}
int create_tree(int inorder_start,int postorder_start,int length)
{
if(length<=0){
return 0;
}
int root = postorder[postorder_start+length-1];
int count =0;
while(inorder[inorder_start+count]!=root){
count ++;
}
T_left[root]=create_tree(inorder_start,postorder_start,count);
T_right[root]=create_tree(inorder_start+count+1,postorder_start+count,length-1-count);
return root;
}
//int create_tree(int inorder_start,int postorder_start,int length)
//{
// if(length<=0){
// return 0;
// }
// int root = postorder[length-1];
// int count =0;
// while(inorder[count]!=root){
// count ++;
// }
// T_left[root]=create_tree(0,0,count);
// T_right[root]=create_tree(count+1,count,length-1-count);
// return root;
//}
void findmin(int root,int sum)
{
sum+=root;
if(T_left[root]==0&&T_right[root]==0){
if(sum0) findmin(T_left[root],sum);
if(T_right[root]>0) findmin(T_right[root],sum);
}
int main()
{
while(readline(inorder)){
readline(postorder);
min_sum=0xfffffff,min_root=0xfffffff;
create_tree(0,0,n);
findmin(postorder[n-1],0);
cout<