二叉树的遍历

二叉树属于子节点有序的有根树.
二叉树的遍历有三种方式:

  • 前序 (pre-order)
  • 中序 (in-order)
  • 后续 (post-order)

这三种遍历方式都是递归定义/实现的.
如果给每个节点一个编号, 就可以得到一个节点序列.
常见的问题:

  • 已知前序, 中序, 求后序.
  • 已知后序, 中序, 求前序.

首先应当注意到, 无论那种遍历方式, 一棵子树中的点在节点序列中是连续的 (后者说占据节点序列中的某连续段).
这样, 我们就可以递归的来解这个问题, 以求后序为例:
solve(l1, r1, l2, l2, L, R)求前序在区间\([l_1, r_1]\)内, 中序在区间\([l_2, r_2]\)内, 后序在\([L, R]\)内的子树的后序遍历序列.
我们首先要确定根, 根是前序序列的第一个/后序序列的最后一个. 然后要确定左右子树的大小, 中序序列中根之前的是左子树的中序序列, 根之后的是右子树的中序序列.
因此, 只有知道了中序和其他某个序的节点序列, 才能求出第三个序的节点序列. 否则左右子树的大小不能唯一确定.

例题 hihocoder #1049 后续遍历

Implementation

#include <bits/stdc++.h>
using namespace std;

const int N{30};

char pre[N], in[N];

void solve(int l1, int r1, int l2, int r2){
    if(l1==r1) return;
    char root=pre[l1];
    for(int i=l2; i<r2; i++){
        if(in[i]==root){
            int l_size=i-l2;
            solve(l1+1, l1+1+l_size, l2, i);
            solve(l1+1+l_size, r1, i+1, r2);
            putchar(root);
        }
    }
}

int main(){
    cin>>pre>>in;
    int n=strlen(pre);
    solve(0, n, 0, n);
    puts("");
    return 0;
}
posted @ 2016-09-09 16:13  Pat  阅读(306)  评论(0编辑  收藏  举报