什么是求和树:二叉树的求和树, 是一颗同样结构的二叉树,其树中的每个节点将包含原始树中的左子树和右子树的和。
二叉树:
求和树:
二叉树给出前序和中序输入,求和树要求中序输出;
所有处理数据不会大于int;
数据范围:二叉树的节点数满足
,节点上的值满足 
2行整数,第1行表示二叉树的前序遍历,第2行表示二叉树的中序遍历,以空格分割
1行整数,表示求和树的中序遍历,以空格分割
10 -2 8 -4 6 7 5 8 -2 -4 10 7 6 5
0 4 0 20 0 12 0
"""
本题有如下规律:
求和树的根节点 = 除本身外原二叉树所有子节点之和,
本题中根节点为中序遍历数组中正中间项(满二叉树)
递归求得左右子树,直到子树节点个数为1返回[0]。
需要考虑根节点在两侧的情况,树节点个数为0时,返回空[]
"""
def func(d):
if len(d) == 1: return [0]
elif len(d) == 0: return []
mid = len(d) // 2 # 满二叉树根节点即正中间数值,前序遍历数组本题中用不到,可删除
return func(d[:mid]) + [sum(d[:]) - d[mid]] + func(d[mid + 1:])
if __name__ == "__main__":
a = list(map(int, input().strip().split()))
d = list(map(int, input().strip().split()))
ans = func(d)
print(' '.join(map(str, ans)))
"""
本题有如下规律:
求和树的根节点 = 除本身外所有子节点之和,
递归求得左右子树,直到子树节点个数为1返回[0]。
需要考虑根节点在两侧的情况,树节点个数为0时,返回空[]
"""
import sys
def func(a, d):
if len(a) == 1:
return [0]
elif len(a) == 0:
return []
mid = d.index(a[0])
d[mid] = sum(d[:]) - d[mid]
return func(a[1:(mid + 1)], d[:mid]) + \
[sum(d[:]) - d[mid]] + \
func(a[(mid + 1):], d[mid + 1:])
if __name__ == "__main__":
# sys.stdin = open('input.txt', 'r')
a = list(map(int, input().strip().split()))
d = list(map(int, input().strip().split()))
ans = func(a, d)
print(' '.join(map(str, ans)))
/*
关键思路:二叉树加一个sum属性。
根据先序中序的序列,构建二叉树。
利用后序遍历来更新节点sum值。
最后通过中序遍历得到答案序列。
估计有更好的方法。
希望同学们有更巧妙的办法后叫我一下。
*/
import java.util.*;
class STNode {
int val;
int sum;
STNode left = null;
STNode right = null;
public STNode(int val) {
this.val = val;
}
}
public class Main {
static int[] preOrder;
static int[] inOrder;
static List<Integer> ans; //存和的中序遍历。
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s1 = in.nextLine();
String s2 = in.nextLine();
String[] str1 = s1.split(" ");
String[] str2 = s2.split(" ");
int len = str1.length;
preOrder = new int[len];
inOrder = new int[len];
for (int i = 0; i < len; i++) {
preOrder[i] = Integer.parseInt(str1[i]);
}
for (int i = 0; i < len; i++) {
inOrder[i] = Integer.parseInt(str2[i]);
}
STNode sroot = creatTree(0, 0, len - 1);
sumNode(sroot);
ans = new ArrayList<>();
inOrderGo(sroot);
for (int i : ans) {
System.out.print(i + " ");
}
System.out.println();
}
//根据先序和中序遍历构建二叉树。
static STNode creatTree(int root, int beg, int end) {
if (beg > end) return null;
STNode node = new STNode(preOrder[root]);
int loc = 0;
int cnt = 0;
for (loc = beg; loc <= end; loc++) {
cnt++;
if (preOrder[root] == inOrder[loc])
break;
}
node.left = creatTree(root + 1, beg, loc - 1);
node.right = creatTree(root + cnt, loc + 1, end);
return node;
}
//更新sum值。
static void sumNode(STNode node) {
if (node.left == null && node.right == null) {
node.sum = 0;
} else if (node.left == null) {
sumNode(node.right);
node.sum = node.right.sum + node.right.val;
} else if (node.right == null) {
sumNode(node.left);
node.sum = node.left.sum + node.left.val;
} else {
sumNode(node.left);
sumNode(node.right);
node.sum = node.left.sum + node.left.val + node.right.sum + node.right.val;
}
}
//中序遍历。
static void inOrderGo(STNode node) {
if (node == null) return;
inOrderGo(node.left);
ans.add(node.sum);
inOrderGo(node.right);
}
}
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
sc.nextLine();//满二叉树应该只需要中序遍历就可以确定唯一的树,所以不保存第一行输入
String zhong = sc.nextLine();
String[] split = zhong.split(" ");
int[] a = new int[split.length];//中序遍历保存到数组a中
for(int i=0;i<a.length;i++) {
a[i] = Integer.parseInt(split[i]);
}
int[] ans = new int[a.length];//保存中序遍历的输出结果
fun(a,0,a.length-1,ans);
for(int i:ans){
System.out.print(i+" ");
}
sc.close();
}
private static int fun(int[] a,int left,int right,int[] ans) {
int mid = (right+left)/2;//中间元素不参与这一轮的计算
if(right-left==2) {//出口条件
ans[mid] = a[right] + a[left];
ans[left] = 0;
ans[right] = 0;
return a[mid]+ans[mid];
}else {
ans[mid] = fun(a,left,mid-1,ans) + fun(a,mid+1,right,ans);
return a[mid]+ans[mid];
}
}
} class TreeNode:
def __init__(self,val):
self.val = val
self.left = None
self.right = None
class Solution:
def createTree(self,preOrder,midOrder):
if len(preOrder) ==0 :
return None
root_index = midOrder.index(preOrder[0])
if len(preOrder) == 1:
root = TreeNode(0)
else:
root = TreeNode(sum(preOrder[1:]))
left_pre = preOrder[1:root_index+1]
right_pre = preOrder[root_index+1:]
left_mid = midOrder[0:root_index]
right_mid = midOrder[root_index+1:]
root.left = self.createTree(left_pre,left_mid)
root.right = self.createTree(right_pre,right_mid)
return root
def midTreverse(self,root):
if root == None:
return []
return self.midTreverse(root.left) + [root.val] + self.midTreverse(root.right)
s = Solution()
preOrder = [int(x) for x in input().split()]
midOrder = [int(x) for x in input().split()]
root = s.createTree(preOrder,midOrder)
print(" ".join(list(map(str,s.midTreverse(root))))) //只通过60%,没有考虑到节点重复的情况
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
String s1=sc.nextLine();
String s2=sc.nextLine();
String[] str1=s1.split(" ");
String[] str2=s2.split(" ");
int[] preorder=new int[str1.length];
int[] inorder=new int[str2.length];
int n=preorder.length;
for(int i=0;i<preorder.length;i++){
preorder[i]=Integer.parseInt(str1[i]);
inorder[i]=Integer.parseInt(str2[i]);
}
func(preorder,0,n-1,inorder,0,n-1);
for(int i=0;i<n;i++){
System.out.print(inorder[i]);
if(i!=n-1){
System.out.print(" ");
}
}
}
public static void func(int[] preorder,int ps,int pl,int[] inorder,int is,int il){
if(ps==pl){
inorder[is]=0;
return;
}
int rootVal=preorder[ps];
int im=is;
while(im<=il && inorder[im]!=rootVal){
im++;
}
inorder[im]=sum(inorder,is,im-1)+sum(inorder,im+1,il);
func(preorder,ps+1,ps+im-is,inorder,is,im-1);
func(preorder,ps+im-is+1,pl,inorder,im+1,il);
}
public static int sum(int[] inorder,int s,int l){
int sum=0;
for(int i=s;i<=l;i++){
sum+=inorder[i];
}
return sum;
}
} #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
const int BUFFER_SIZE = 1024;
const char* const DELIM = " ";
typedef int ElemType;
// The definition of Binary Tree Node
typedef struct TreeNode {
ElemType data;
struct TreeNode* left;
struct TreeNode* right;
} TreeNode, *PTreeNode;
// =================== The begin of function declaration ====================
// 将普通的二叉树转换为求和树
int convertToSumTree(PTreeNode root);
// 把二叉树节点的数据成员打印在公屏上
void printTreeNodeData(PTreeNode node);
// 中序遍历二叉树
void inorderTraversal(PTreeNode root, void (*visit) (PTreeNode));
// 根据二叉树的先序(前序)和中序遍历序列构造二叉树本体
PTreeNode constructTree(const int* preorder, const int* inorder, int i, int j, int n);
// debug helper function
void __printArray(int* arr, const int size);
// =================== The end of function declaration ====================
int main(const int argc, const char* argv[]) {
char pre_str[1 << 10] = { 0 }, in_str[1 << 10] = { 0 };
fgets(pre_str, BUFFER_SIZE, stdin);
fgets(in_str, BUFFER_SIZE, stdin);
int preorder[1024], inorder[1024],
preorderSize = 0, inorderSize = 0;
char* tok = strtok(pre_str, DELIM);
while (tok) {
*(preorder + preorderSize++) = atoi(tok);
tok = strtok(NULL, DELIM);
}
tok = strtok(in_str, DELIM);
while (tok) {
*(inorder + inorderSize++) = atoi(tok);
tok = strtok(NULL, DELIM);
}
PTreeNode root = constructTree(preorder, inorder, 0, 0, preorderSize);
convertToSumTree(root); // 将普通的二叉树转换为求和树
return inorderTraversal(root, printTreeNodeData), 0;
}
int convertToSumTree(PTreeNode root) {
if (!root) return 0;
const int left = convertToSumTree(root->left);
const int right = convertToSumTree(root->right);
const int sum = root->data + left + right;
root->data = left + right;
return sum;
}
PTreeNode constructTree(const int* preorder, const int* inorder, int i, int j, int n) {
if (n <= 0) return NULL;
PTreeNode root = (PTreeNode) malloc(sizeof(TreeNode));
if (!root) {
fprintf(stderr, "constructTree memory overflow: %s\n", strerror(errno));
return NULL;
}
(*root).data = *(preorder + i);
(*root).left = (*root).right = NULL;
if (n == 1) return root;
int k = j;
while (*(inorder + k) != *(preorder + i)) ++k;
int l = k - j;
root->left = constructTree(preorder, inorder, i + 1, j, l);
root->right = constructTree(preorder, inorder, i + 1 + l, k + 1, n - 1 - l);
return root;
}
void printTreeNodeData(PTreeNode node) {
fprintf(stdout, "%d ", (*node).data);
}
void inorderTraversal(PTreeNode root, void (*visit) (PTreeNode)) {
if (!root) return;
inorderTraversal((*root).left, visit);
visit(root);
inorderTraversal((*root).right, visit);
}
void __printArray(int* arr, const int size) {
int i;
for (i = 0; i < size; ++i) {
fprintf(stdout, "%2d", *(arr + i));
if (i < size - 1) fputc(32, stdout);
}
fputc(10, stdout);
} import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
br.readLine(); // 忽略先序遍历
String[] strArr = br.readLine().trim().split(" ");
ArrayList<Integer> inOrder = new ArrayList<>();;
for(int i = 0; i < strArr.length; i++) inOrder.add(Integer.parseInt(strArr[i]));
ArrayList<Integer> res = sumTree(inOrder);
for(int i = 0; i < res.size(); i++)
System.out.print(res.get(i) + " ");
System.out.println();
}
private static ArrayList<Integer> sumTree(ArrayList<Integer> seq) {
// 到达叶子节点就返回0
if(seq.size() == 1){
ArrayList<Integer> temp = new ArrayList<>();
temp.add(0);
return temp;
}
// 本子树的根节点
int root = seq.size() / 2;
int sum = 0; // 初始化本结点的左右子树和
// 左子树序列
ArrayList<Integer> leftTree = new ArrayList<>();
for(int i = 0; i < root; i++) {
leftTree.add(seq.get(i));
sum += seq.get(i);
}
// 对左子树进行求和操作
leftTree = sumTree(leftTree);
// 右子树序列
ArrayList<Integer> rightTree = new ArrayList<>();
for(int i = root + 1; i < seq.size(); i++) {
rightTree.add(seq.get(i));
sum += seq.get(i);
}
// 对右子树进行求和操作
rightTree = sumTree(rightTree);
leftTree.add(sum);
leftTree.addAll(rightTree);
return leftTree;
}
} /*等成绩ing,希望我上岸- -。*/
#include <bits/stdc++.h>
using namespace std;
const int AX = 1e5 + 666 ;
char s[AX] ;
vector<int>pre_v , in_v ;
int sum[AX] ;
struct TreeNode{
int val ;
int sum ;
TreeNode *l ;
TreeNode *r ;
TreeNode( int val ) : val(val) , sum(0) , l(NULL), r(NULL) {}
};
void input(){
fgets( s , AX , stdin );
char *p = strtok( s , " " ) ;
while( p ){
pre_v.push_back(atoi(p));
p = strtok( NULL , " " );
}
fgets( s , AX , stdin );
p = strtok( s , " " ) ;
while( p ){
in_v.push_back(atoi(p));
p = strtok( NULL , " " );
}
}
TreeNode* build( vector<int>pre , vector<int>in ){
if( !pre.size() || !in.size() ){
return NULL ;
}
TreeNode* rt = new TreeNode(pre[0]);
for( int i = 0 ; i < in.size() ; i++ ){
if( in[i] == pre[0] ){
vector<int>p1( pre.begin() + 1 , pre.begin() + i + 1 );
vector<int>v1( in.begin() , in.begin() + i ) ;
rt->l = build( p1 , v1 );
vector<int>p2( pre.begin() + i + 1 , pre.end() );
vector<int>v2( in.begin() + i + 1 , in.end() ) ;
rt->r = build( p2 , v2 );
break ;
}
}
return rt ;
}
int dfs( TreeNode *rt ){
if( rt == NULL ) return 0 ;
int ans = 0 ;
if( rt -> l ) ans += dfs( rt -> l );
if( rt -> r ) ans += dfs( rt -> r );
rt -> sum = ans ;
return ans + rt -> val ;
}
void in_order(TreeNode* rt){
if( rt -> l ) in_order( rt -> l );
cout << rt -> sum << ' ' ;
if( rt -> r ) in_order( rt -> r );
}
int main(){
input();
TreeNode* root = build( pre_v , in_v ) ;
dfs( root );
int len = in_v.size() ;
in_order(root);
return 0 ;
} #include <iostream>
#include <vector>
using namespace std;
vector<int> t1;
vector<int> t2;
vector<int>* res;
int main() {
int sumTree(int l, int r);
int i = 0;
char c = ' ';
vector<int>* t = &t1;
while (cin) {
cin >> noskipws >> i >> c;
t->push_back(i);
if (c == '\n') {
if (t != &t2)
t = &t2;
else
break;
}
}
res = new vector<int>((t1.size()));
sumTree(0, t1.size() - 1);
for (int i = 0; i < res->size(); i++) {
cout << (*res)[i];
if (i + 1 != res->size()) {
cout << ' ';
}
else {
cout << endl;
}
}
return 0;
}
int curNode = 0;
int sumTree(int l,int r) {
int sum = 0;
if (l >= r) {
if (curNode >= t1.size())
return 0;
return t1[curNode];
}
int curV = t1[curNode];
int pos = 0;
for (int i = l; i <= r; i++) {
if (t2[i] == t1[curNode]) {
pos = i;
break;
}
}
curNode++;
sum += sumTree(l, pos-1);
curNode++;
sum += sumTree(pos + 1, r);
int resPos = (l + r) / 2;
if ((l + r) % 2)
resPos++;
(*res)[resPos] = sum;
sum += curV;
return sum;
} 写完才发现是满二叉树,我枯了
import java.util.*;
class TreeNode{
int val;
TreeNode left = null;
TreeNode right = null;
TreeNode(int val) {this.val = val;}
}
public class Main{
public static void main(String []args){
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()){
String[] str1 = sc.nextLine().split(" ");
String[] str2 = sc.nextLine().split(" ");
int[] pre = new int[str1.length];
int[] in = new int[str2.length];
for (int i=0;i<pre.length;i++){
pre[i] = Integer.valueOf(str1[i]);
in[i] = Integer.valueOf(str2[i]);
}
TreeNode root = reCon(pre, in);
root = SumTree(root);
InOrderPrint(root);
}
}
public static void InOrderPrint(TreeNode root){
if (root == null) return;
InOrderPrint(root.left);
System.out.print(root.val+" ");
InOrderPrint(root.right);
}
public static TreeNode reCon(int[] pre, int[] in){
if (pre.length == 0) return null;
TreeNode root = new TreeNode(pre[0]);
for (int i=0;i<in.length;i++)
if (in[i] == pre[0]){
root.left = reCon(Arrays.copyOfRange(pre, 1, i+1), Arrays.copyOfRange(in, 0, i));
root.right = reCon(Arrays.copyOfRange(pre, i+1, pre.length), Arrays.copyOfRange(in, i+1, in.length));
}
return root;
}
public static TreeNode SumTree(TreeNode root){
if (root == null) return root;
TreeNode newroot = new TreeNode(Sum(root)-root.val);
newroot.left = SumTree(root.left);
newroot.right = SumTree(root.right);
return newroot;
}
public static int Sum(TreeNode root){
if (root == null) return 0;
return root.val+Sum(root.left)+Sum(root.right);
}
} #include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int tree[N], res[N], mark[N];
vector<int> foo, bar;
void read(vector<int> &vec){
int num = 0, sg = 1;
char c;
while((c = getchar()) != '\n'){
if(c != ' '){
if(c != '-'){
num = num * 10 + (c - '0');
} else {
sg = -1;
}
} else {
vec.push_back(num * sg);
num = 0;
sg = 1;
}
}
vec.push_back(num * sg);
}
void ask(int index, int lf, int rf, int lb, int rb){
if(lf > rf || lb > rb){
return;
}
int llen, need;
tree[index] = foo[lf];
mark[index] = 0;
for (int i = lb; i <= rb; i++){
if(bar[i] == foo[lf]){
need = i;
break;
}
}
llen = need - lb;
ask(index * 2, lf + 1, lf + llen, lb, rb + llen - 1);
ask(index * 2 + 1, lf + llen + 1, rf, need + 1, rb);
}
void print(int index){
if(mark[index] == -1){
return;
}
print(index * 2);
cout << res[index] << " ";
print(index * 2 + 1);
}
int main(){
read(foo);
read(bar);
memset(mark, -1, sizeof(mark));
int len, depth;
len = foo.size() - 1;
depth = (int)log2(len + 1) + 1;
ask(1, 0, len, 0, len);
for (int i = depth; i >= 1; i--){
int start = (1 << i);
for (int j = 0, k = start; j < start / 2; j++, k += 2){
res[k / 2] = res[k] + res[k + 1];
if(mark[k] != -1){
res[k / 2] += tree[k];
}
if(mark[k + 1] != -1){
res[k / 2] += tree[k + 1];
}
}
}
print(1);
return 0;
} #include <bits/stdc++.h>
using namespace std;
void DFS(vector<int> pre, vector<int> in, int p, int l, int r, vector<int> &v){
if(l>r)
return;
else if(l==r)
v[l] = 0;
else{
int s = 0;
for(int i=l;i<=r;i++)
s += in[i];
int k = l;
for(;k<=r;k++){
if(in[k] == pre[p]){
break;
}
}
s -= in[k];
v[k] = s;
DFS(pre, in, p+1, l, k-1, v);
DFS(pre, in, p+k-l+1, k+1, r, v);
}
}
int main(){
string s, x;
getline(cin, s);
vector<int> pre;
vector<int> in;
istringstream ss(s);
while(ss>>x)
pre.push_back(stoi(x));
getline(cin, s);
istringstream ss1(s);
while(ss1>>x)
in.push_back(stoi(x));
int n = pre.size();
vector<int> v(n, 0);
DFS(pre, in, 0, 0, n-1, v);
for(int i=0;i<n;i++)
cout<<v[i]<<" ";
return 0;
} 虽然过了,但感觉只适用于没有重复节点的情况,贴出来给大家查看一下,思路不难就是利用二叉树的特性进行标记再求和!
import java.util.Scanner;
public class Main {
private static int getIdx(String[] nums, String target) {
for (int i = 0; i < nums.length; i++) {
if (nums[i].equals(target)) return i;
}
return -1;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String preOrder = sc.nextLine();
String inOrder = sc.nextLine();
String[] preNumbers = preOrder.split(" ");
String[] inNumbers = inOrder.split(" ");
int n = inNumbers.length;
int[] ans = new int[n];
boolean[] used = new boolean[n];
for (String preNumber : preNumbers) {
int idx = getIdx(inNumbers, preNumber);
int i = idx - 1;
while (i >= 0 && !used[i]) {
ans[idx] += Integer.valueOf(inNumbers[i--]);
}
int j = idx + 1;
while (j < n && !used[j]) {
ans[idx] += Integer.valueOf(inNumbers[j++]);
}
used[idx] = true;
}
for (int i = 0; i < n; i++) {
System.out.print(ans[i]);
if (i != n - 1) System.out.print(' ');
}
}
}
}
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#include <numeric>
using namespace std;
void sumtree(vector<int> &inorder, int left, int right){
int mid = (left + right)/2;
if(mid == left){
inorder[mid] = 0;
return;
}
inorder[mid] = accumulate(inorder.begin()+left, inorder.begin()+right, -inorder[mid]);
sumtree(inorder, left, mid);
sumtree(inorder, mid+1, right);
}
int main(void){
string line;
getline(cin, line);
istringstream pre_stream(line);
vector<int> preorder((istream_iterator<int>(pre_stream)), istream_iterator<int>());
getline(cin, line);
istringstream in_stream(line);
vector<int> inorder((istream_iterator<int>(in_stream)), istream_iterator<int>());
sumtree(inorder, 0, inorder.size());
copy(inorder.begin(), inorder.end(),ostream_iterator<int>(cout, " "));
cout<<endl;
return 0;
} 因为是满二叉树,其实结果跟前序遍历数组无关,只和中序遍历数组有关,并且中序数组一定是奇数个,结果索引为偶数的一定为0,索引为奇数的值是中序遍历数组其他值之和(不包括自己),使用二分法找到根节点,然后计算子树之和,不用还原二叉树。// 核心方法
public Integer help(int [] nums,int low,int high) {
if(low == high) {
int tmp = nums[low];
nums[low] = 0;
return tmp;
}
int sum = 0;
int mid = (low+high)/2;
sum += help(nums,low,mid-1); //用记录左右孩子的和
sum += help(nums,mid+1,high);
int tmp = nums[mid];
nums[mid] = sum;
return sum + tmp; // 返回原来的值和新的值
} import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
List<Integer> list = new ArrayList<>();
while(sc.hasNext()){
list.add(sc.nextInt());
}
int[] preOrder = new int[list.size()/2];
int[] inOrder = new int[list.size()/2];
for(int i=0;i<list.size();i++){
if(i < list.size()/2)
preOrder[i] = list.get(i);
else
inOrder[i-list.size()/2] = list.get(i);
}
TreeNode root = createTree(preOrder,0,preOrder.length-1,inOrder,0,inOrder.length-1);
dfs(root);
}
//中序遍历输出结果
public static void dfs(TreeNode root){
if(root == null)
return;
dfs(root.left);
int num = PrintNode(root);
System.out.print(num + " ");
dfs(root.right);
}
//打印节点
public static int PrintNode(TreeNode root){
if(root == null)
return 0;
int Left = 0,Right = 0;
if(root.left != null)
Left = root.left.val;
if(root.right != null)
Right = root.right.val;
return Left + Right + PrintNode(root.left) + PrintNode(root.right);
}
//建树
public static TreeNode createTree(int[] preOrder,int preStart,int preEnd,int[] inOrder,int inStart,int inEnd){
if(preStart > preEnd || inStart > inEnd)
return null;
int target = preOrder[preStart];
TreeNode root = new TreeNode(target);
int index;
for(index=inStart;index<=inEnd;index++)
if(inOrder[index] == target)
break;
int leftLength = index-inStart;
root.left = createTree(preOrder,preStart+1,preStart+leftLength,inOrder,inStart,index-1);
root.right = createTree(preOrder,preStart+leftLength+1,preEnd,inOrder,index+1,inEnd);
return root;
}
}
//构造树
class TreeNode{
int val;
TreeNode left;
TreeNode right;
public TreeNode(int x){val = x;}
} #include <iostream>
#include <memory>
#include <sys/types.h>
#include <vector>
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode():val(0),left(nullptr),right(nullptr){};
TreeNode(int x):val(x),left(nullptr),right(nullptr){};
};
TreeNode* buildTree(vector<int>&preOrder,vector<int>&inOrder){
if(preOrder.size()==0) return nullptr;
int root_val=preOrder[0];
TreeNode* root=new TreeNode(root_val);
int mid_idx=0;
for(int i=0;i<inOrder.size();i++){
if(inOrder[i]==root_val)
mid_idx=i;
}
vector<int>leftinOrder(inOrder.begin(),inOrder.begin()+mid_idx);
vector<int>rightinOrder(inOrder.begin()+mid_idx+1,inOrder.end());
vector<int>leftpreOrder(preOrder.begin()+1,preOrder.begin()+leftinOrder.size()+1);
vector<int>rightpreOrder(preOrder.begin()+leftinOrder.size()+1,preOrder.end());
root->left=buildTree(leftpreOrder,leftinOrder);
root->right=buildTree(rightpreOrder,rightinOrder);
return root;
}
int dfs(TreeNode* node){
if(node==nullptr) return 0;
int sum=0;
sum+=dfs(node->left);
sum+=dfs(node->right);
int temp=node->val+sum;
node->val=sum;
return temp;
}
void myprint(TreeNode* node){
if(node==nullptr) return;
myprint(node->left);
cout<<node->val<<" ";
myprint(node->right);
}
int main() {
vector<int>preOrder,inOrder;
int x;
while(cin>>x){
preOrder.push_back(x);
if(cin.get()=='\n') break;
}
while(cin>>x){
inOrder.push_back(x);
if(cin.get()=='\n') break;
}
if(preOrder.size()==0||inOrder.size()==0) return 0;
TreeNode* root=buildTree(preOrder,inOrder);
dfs(root);
myprint(root);
} #include<bits/stdc++.h>
using namespace std;
void help(vector<int>& tree,int l,int r)
{
if(l==r)
tree[l]=0;
int m=(l+r)/2;
tree[m]=0;
for(int i=l;i<=r;i++)
{
if(i!=m)
tree[m]+=tree[i];
}
}
void help1(vector<int>& tree,int l,int r)
{
if(l>r)
return;
int m=(l+r)/2;
help(tree,l,r);
help1(tree,l,m-1);
help1(tree,m+1,r);
}
int main()
{
vector<int> tree;
int a;
while(cin>>a)
{
tree.push_back(a);
}
int n=tree.size();
vector<int> t(tree.begin()+n/2,tree.end());
int l=0,r=t.size()-1;
help1(t,l,r);
for(auto it:t)
cout<<it<<" ";
return 0;
}
仅利用中序遍历即可得出最终答案,在满二叉树中,根节点是中间节点,把根节点左右两边的值 加起来就是根节点的结果,然后利用递归求根节点的左右节点的值,其中help1函数是为了确定节 点计算的范围,help函数是为了计算。