二叉树3(恢复二叉树)
从中序和后序恢复二叉树
给一颗带权(权值各不相同,都是小于10000的正整数)的二叉树的中序和后序遍历序列,找一个叶子使得它到根的路径上的权值尽可能小,如果有多解,取叶子权值小的。输入中第一行为中序遍历,第二行为后序遍历。
例如输入:
3 2 1 4 5 7 6
3 1 2 5 6 7 4
输出
1
输入:
7 8 11 3 5 16 12 18
8 3 11 7 16 18 12 5
输出:
3
#include"iostream" using namespace std; typedef int element; element minweight = 20000; element minleaf; class Tree{ private: element data; Tree *right,*left; public: Tree(element data = 0){ this->data = data; right = NULL; left = NULL; } void usezhCreate(Tree* &t,element *z,element *h,int len){ if(len == 1){ t = new Tree(z[0]); //如果还剩1个值了,直接创建叶子 } else{ int llen = 0; //左子树长度 for(int i = 0;i < len;i++){ if(z[i] == h[len - 1]){ llen = i; break; } } int rlen = len - llen - 1; //右子树长度 element *zl = new element[llen]; element *zr = new element[rlen]; element *hl = new element[llen]; element *hr = new element[rlen]; //核心拆分 for(i = 0;i < llen;i++){ zl[i] = z[i]; hl[i] = h[i]; } for(i = 0;i < rlen;i++){ zr[i] = z[i + llen + 1]; hr[i] = h[i + llen]; } t = new Tree(h[len - 1]); //长度大于0 就继续创建树 if(llen > 0){ usezhCreate(t->left,zl,hl,llen); } if(rlen > 0){ usezhCreate(t->right,zr,hr,rlen); } delete[] zl; delete[] zr; delete[] hl; delete[] hr; } } void minPath(element w = 0){ if(this){ w += data; if(left == NULL && right == NULL){ if(minweight > w){ minweight = w; minleaf = data; } return ; } left->minPath(w); right->minPath(w); } } }; int main(){ Tree *t = NULL; int z[10000],h[10000]; for(int i = 0;i < 10000;i++){ cin>>z[i]; if(cin.get() == '\n'){ break; } } for(i = 0;i < 10000;i++){ cin>>h[i]; if(cin.get() == '\n'){ break; } } t->usezhCreate(t,z,h,i + 1); t->minPath(); cout<<minleaf<<endl; return 0; } /* 7 8 11 3 5 16 12 18 8 3 11 7 16 18 12 5 3 2 1 4 5 7 6 3 1 2 5 6 7 4 */
BY oleolema