CodeVS 1013&1029

若干二叉树遍历的数据结构题。

Problem 1013

传送门:http://codevs.cn/problem/1013/

本题是一个数据结构——二叉树遍历问题。

对二叉树,给定中序遍历序列(In-order Traverse Sequence)和后序遍历序列(Post-order Traverse Sequence),求此二叉树的前序遍历序列(Pre-order Traverse Sequence)。

a.前序遍历:root->left sub-tree->right sub-tree;

b.中序遍历:left sub-tree->root->right sub-tree;

c.后序遍历:left sub-tree->right sub-tree->root;

于是,对于中序序列s与后序序列t,考虑分别将其分成三部分:根结点、左子树、右子树。设给定序列的长度为len,则root在后序序列t中的位置为len(后序序列中的最后一个位置为根结点)。设root在中序序列s中的位置为pos,则左子树的中序序列为s[1..pos-1],右子树的中序序列为s[pos+1..len]。于是,左子树的后序序列为t[1..pos-1],右子树的后序序列为t[pos..len-1]。递归地求解当前的根结点即可。

参考程序如下:

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

void dfs(string s, string t)
{
    if (!s.length()) return;
    //root
    int len = s.length();
    int pos = s.find(t.at(len - 1));
    printf("%c", t.at(len - 1));
    //left subtree
    int l = pos;
    dfs(s.substr(0, l), t.substr(0, l));
    //right subtree
    int r = len - pos - 1;
    dfs(s.substr(pos + 1, r), t.substr(pos, r));
}

int main(void)
{
    string s, t;
    cin >> s >> t;
    dfs(s, t);
    return 0;
}

Problem 1029

传送门:http://codevs.cn/problem/1029/

本题是一个数据结构——二叉树遍历问题。

对二叉树,给定前序遍历序列(Pre-order Traverse Sequence)和后序遍历序列(Post-order Traverse Sequence),求此二叉树的中序遍历序列(In-order Traverse Sequence)的所有可能情况数。

中序序列的不唯一性,来源于“无sibling的叶结点”。设前序序列和后序序列分别为st,设这个叶结点在s中的位置为i,在t中的位置为j,即s[i]==t[j]。由于这个结点无sibling,于是其parent在s中的位置为i-1,在t中的位置为j+1,即s[i-1]==t[j+1]。统计所有的“无sibling的叶结点”:cnt=card{(i,j)|1<i≤n,1≤j<n,s[i]=t[j],s[i-1]=t[j+1]}。则所有可能情况数为2cnt

参考程序如下:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char s[32], t[32];
    scanf("%s%s", s, t);
    int cnt = 0;
    for (int i = 1; i < strlen(s); i++) {
        for (int j = 0; j < strlen(t) - 1; j++) {
            if (s[i] == t[j] && s[i - 1] == t[j + 1]) cnt++;
        }
    }
    printf("%lld
", 1LL << cnt);
    return 0;
}

 

原文地址:https://www.cnblogs.com/siuginhung/p/7726606.html