zoukankan      html  css  js  c++  java
  • UVa 548 Tree【二叉树的递归遍历】

    题意:给出一颗点带权的二叉树的中序和后序遍历,找一个叶子使得它到根的路径上的权和最小。

    学习的紫书:先将这一棵二叉树建立出来,然后搜索一次找出这样的叶子结点

    虽然紫书的思路很清晰= =可是理解起来好困难啊啊啊啊

    后来终于问懂一丢丢了---

    比如说样例:

    中序遍历:3 2 1 4 5 7 6

    后序遍历:3 1 2 5 6 7 4

    首先做第一层: 在后序遍历中的最后一个数为根节点,然后在到中序遍历中找到这个根节点,在这个根节点的左边是左子树,右边是右子树,这样就确定出了左子树和右子树的区间

    然后做第二层 中序遍历左子树的长度等于后序遍历中左子树的长度 即为在这个样例中:

    中序遍历的左子树为 3 2 1   后序遍历的左子树为3 1 2 然后又可以确定2为这颗左子树的一个根节点,又可以将 3 2 1划分成左右子树区间

    就这样一层一层划分建树

    概括一下就是:

    中序遍历序列:【左子树区间中序遍历序列】【根】【右子树区间中序遍历序列】

    后序遍历序列:【左子树区间中序遍历序列】【右子树区间中序遍历序列】【根】

    话说build函数也理解了好久的说 = =

    对于lch[root]=build(L1,p-1,L2,L2+cnt-1);L1到p-1是在中序遍历中的左子树 L2到L2+cnt-1是在后序遍历中的左子树

    对于rch[root]=build(p+1,R1,L2+cnt,R2-1);p+1到R1是在中序遍历中的右子树

    L2+cnt到R2-1是在后序遍历中的右子树

     1 #include<iostream>  
     2 #include<cstdio>  
     3 #include<cstring> 
     4 #include <cmath>   
     5 #include<algorithm>  
     6 #include<sstream>
     7 using namespace std;
     8 
     9 typedef long long LL;
    10 const int maxn=10000+5;
    11 int in_order[maxn],post_order[maxn],lch[maxn],rch[maxn];
    12 int n;
    13 
    14 bool read_list(int *a){
    15     string line;
    16     if(!getline(cin,line)) return false;
    17     stringstream ss (line);
    18     n=0;
    19     int x;
    20     while(ss>>x) a[n++]=x;
    21     return n>0;
    22 }
    23 
    24 int build(int L1,int R1,int L2,int R2){
    25     if(L1>R1) return 0;
    26     int root=post_order[R2];
    27     int p=L1;
    28     while(in_order[p]!=root) p++;
    29     int cnt=p-L1;//左子树的结点个数 
    30     lch[root]=build(L1,p-1,L2,L2+cnt-1);
    31     rch[root]=build(p+1,R1,L2+cnt,R2-1);
    32     return root;
    33 }
    34 
    35 int best,best_sum;
    36 
    37 void dfs(int u,int sum){
    38     sum+=u;
    39     if(!lch[u]&&!rch[u]){
    40         if(sum<best_sum||(sum==best_sum&&u<best)) {
    41         best=u;
    42         best_sum=sum;
    43     }
    44     }
    45     
    46     if(lch[u]) dfs(lch[u],sum);//如果u有左孩子,继续深搜,直到搜到叶子结点 
    47     if(rch[u]) dfs(rch[u],sum);    
    48 }
    49 
    50 int main(){
    51     while(read_list(in_order)){
    52         read_list(post_order);
    53         build(0,n-1,0,n-1);
    54         best_sum=1000000005;
    55         dfs(post_order[n-1],0);
    56         cout<<best<<"
    ";        
    57     }
    58     return 0;
    59 }
    View Code

    go---go---

  • 相关阅读:
    Codeforces Round #313 (Div. 1) A.Gerald's Hexagon
    COJN 0585 800604鸡蛋的硬度
    COJN 0584 800603吃糖果
    COJN 0583 800602分苹果
    COJN 0575 800601滑雪
    昨天的补记
    重构的代码
    写了一个复杂的sql语句
    一个想法
    安装了C
  • 原文地址:https://www.cnblogs.com/wuyuewoniu/p/4331052.html
Copyright © 2011-2022 走看看