• 重建二叉树POJ2255


    重建二叉树

    给定一棵二叉树的前序遍历和中序遍历的结果,求其后序遍历。

    输入输入可能有多组,以EOF结束。
    每组输入包含两个字符串,分别为树的前序遍历和中序遍历。每个字符串中只包含大写字母且互不重复。输出对于每组输入,用一行来输出它后序遍历结果。样例输入

    DBACEGF ABCDEFG
    BCAD CBAD
    

    样例输出

    ACBFGED
    CDAB

    题意:题目很简单,给出一棵树的前序遍历和中序遍历求它的后序遍历(多组数据)
    那么让我们回顾一下树的三种遍历
    1.前序遍历:根左右
    2.中序遍历:左根右
    3.后序遍历:左右根
    真理:1.前序遍历的第一个点是根节点。
     2.中序遍历的根节点左侧是树的左子树,根节点右侧是树的右子树。
     3.后序遍历的最后一个是根节点。
    思路:假设中序遍历中根节点的位置是a,那么后序遍历中0~a个点是树的左子树节点,a~n-2(数组从0开始)个点是树的右子树节点。
    神奇的函数:strchr()是string.h中的函数,strchr(a,b)返回b元素在字符串a中第一次出现的地址c+a字符串的地址(就是c+a数组的地址)
    贴上巨丑无比的代码(注释比代码长QAQ):
     1 #include<stdio.h>
     2 #include<string.h>
     3 void bulid(int n,char s1[],char s2[])//n是树的节点数,s1是记录先序遍历,s2中序遍历 
     4 {
     5     if(n<=0)  return;//没有节点了,找到边界return 
     6     int p=strchr(s2,s1[0])-s2;
     7     // strchr(s2,s1[0])是s2的地址+s1[0]第一次出现的位置i。s2是s2的地址 
     8     //所以p是 s1[0]第一次出现在s2中的位置
     9     bulid(p,s1+1,s2);
    10     //数的节点数为s1[0]在s2中之前的所有节点。s1+1是把s1数组整体向前移动一位(s1[0]是以前的s1[1],s1[1]改为以前s1[2]...
    11     //以前s1[0]是根,现在不需要,所以删除。要它左子树的根节点 
    12     //s2不变(假设中序遍历中根节点的位置是a,那么后序遍历中0~a个点是树的左子树节点) 
    13     bulid(n-p-1,s1+p+1,s2+p+1);
    14     //数的节点数为s1[0]在s2中之后的所有节点(因为数组从0开始,所以-1)
    15     //以前s1[0]是根,现在不需要,左子树也不需要,所以都删除。要它右子树的根节点
    16     //s2+p+1(假设中序遍历中根节点的位置是a,a~n-2(数组从0开始)个点是树的右子树节点 ) 
    17     printf("%c",s1[0]);//输出 
    18 }
    19 int main()
    20 {
    21     char s1[10007],s2[10007];//s1是树的前序遍历,s2是树的中序遍历 
    22     while(scanf("%s %s",s1,s2)!=EOF)//多组数据 
    23     {
    24         bulid(strlen(s1),s1,s2); 
    25         printf("
    ");//记得输出
     
    26     }
    27     return 0;
    28 }/*
    29 先序遍历第一个节点一定是根节点。
    30 中序遍历根节点左侧就是树的左子树,右侧就是树的右子树。
    31 后序遍历最后一个节点一定是根节点,而假设中序序列里根节点位置是m,那么
    32 后序序列里0至m-1个节点是树的左子树节点,m至倒数第二个点是树的右子树节
    33 点。
    34 */ 
    下面给出不加注释的代码(代码比较丑QWQ)
    #include<stdio.h>
    #include<string.h>
    void bulid(int n,char s1[],char s2[])
    {
        if(n<=0)  return;
        int p=strchr(s2,s1[0])-s2;
        bulid(p,s1+1,s2);
        bulid(n-p-1,s1+p+1,s2+p+1);
        printf("%c",s1[0]);
    }
    int main()
    {
        char s1[10007],s2[10007];   
        while(scanf("%s %s",s1,s2)!=EOF)
        {
            bulid(strlen(s1),s1,s2); 
            printf("
    ");
        }
        return 0;
    }
     
  • 相关阅读:
    日期计算
    普通二叉树转换成搜索二叉树
    每周行情
    virtualbox安装增强功能时【未能加载虚拟光盘】
    linux实用命令之如何移动文件夹及文件下所有文件
    Linux文件夹文件创建、删除
    php 克隆 clone
    function_exists (),method_exists()与is_callable()的区别
    webgrind安装使用详细说明
    windows下redis的安装配置和php扩展使用phpredis
  • 原文地址:https://www.cnblogs.com/Peper/p/7241955.html
Copyright © 2020-2023  润新知