问题描述
给出满二叉树,编写算法将其转化为求和树
求和树:二叉树的求和树,是一颗同样结构的二叉树,其树中的每个结点将包含原始树中的左子树和右子树的和。
二叉树:
10
/ \
-2 6
/ \ / \
8 -4 7 5
求和树:
20(4-2+12+6)
/ \
4(8-4) 12(7+5)
/ \ / \
0 0 0 0
输入格式
输入共3行:第一行为满二叉树中结点个数n(n<1024);第二行为n个整数,表示二叉树的先序遍历序列;第三行也有n个整数,表示二叉树的中序遍历序列。整数间以空格分割。
输出格式
输出1行整数,表示求和树的中序遍历序列。整数间以空格分割。
样例输入
7
10 -2 8 -4 6 7 5
8 -2 -4 10 7 6 5
样例输出
0 4 0 20 0 12 0
代码
采取比较传统的方法,由先序和中序序列构树,再对树进行求和,保存在原树的val变量中,最后中序遍历输出。
直接放代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data,val; //data为节点值,val为求和值
struct node* lchild,*rchild;
}Node;
//由先序和中序构树
//在构树时应传入&T
void CreateTree1(Node* &T,int* pre,int* in,int n){
if(n==0)
return;
int i;
for(i=0;i<n;i++){
if(in[i]==*pre)
break;
}
T=(Node*)malloc(sizeof(Node));
T->data=*pre;
T->lchild=T->rchild=NULL;
CreateTree1(T->lchild,pre+1,in,i);
CreateTree1(T->rchild,pre+1+i,in+1+i,n-1-i);
}
//对树求和,保存在原树的val中
void CreateTree2(Node* &T){
if(T->lchild==NULL&&T->rchild==NULL){
T->val=0;
return;
}
else if(T->lchild==NULL){
CreateTree2(T->rchild);
T->val=T->rchild->data+T->rchild->val;
}
else if(T->rchild==NULL){
CreateTree2(T->lchild);
T->val=T->lchild->data+T->lchild->val;
}
else{
CreateTree2(T->lchild);
CreateTree2(T->rchild);
T->val=T->lchild->data+T->lchild->val+T->rchild->data+T->rchild->val;
}
}
void InOrder(Node* T){
if(T==NULL)
return;
InOrder(T->lchild);
printf("%d ",T->val);
InOrder(T->rchild);
}
int main(){
int n;
scanf("%d",&n);
int pre[n],in[n];
int i;
for(i=0;i<n;i++){
scanf("%d",&pre[i]);
}
for(i=0;i<n;i++){
scanf("%d",&in[i]);
}
Node* T;
CreateTree1(T,pre,in,n);
CreateTree2(T);
InOrder(T);
return 0;
}