根据树的前序遍历、中序遍历、后序遍历中的两种遍历求第三种遍历结果

学过数据结构,都知道二叉树有四种遍历手段,前序遍历、中序遍历、后序遍历以及层序遍历,而前三种遍历存在较强的关联,即:知道中序遍历及另外两种遍历中的一种时,可以求第三种,简单的讲就是根据中序遍历和前序遍历、后序遍历中的一种,可以求第三种。
是不是有些绕了,自己慢慢理解吧!我们这里要讲一下实现代码。
遇见这种问题,我听说好像可以用栈来实现,但是今天要说的是通过建树来实现的。
分为两种情况:
1、知道前序遍历和中序遍历,求后序遍历。
                这个相对比较简单,因为我们可以通过查找根结点在中序遍历的位置来对两种遍历序列切割,分成子序列,这样通过递归可以实现建树,并且在递归函数尾加上一条输出语句即可实现后序遍历。
2、知道后序遍历和中序遍历,求前序遍历。
                这个就有些难了,对三种遍历没有教深入理解的人是无法理解透这个算法的,其实和前边的算法大致一样,只是有些许的细节差别,我们同样是要查找根结点在中序遍历中的位置,但是我们不能用同样的手段分隔,我们知道,中序遍历,根结点的左边的都是左子树,右边的都是右子树,而后序遍历中的根结点在尾部,所以想要分隔必须对中序遍历进行以根结点为中心左右分割(不留下根结点),对后序遍历进行的分割要保证前半段的长度和中序遍历的前半段长度一致,后半段去除根结点的部分,这样分成了两段同样也是左右子树,另外输出语句也要提前,因为这是前序遍历,所以输出语句需要在递归函数调用自身前就进行输出。

大致的思路就是这样,先看第一种的代码(代码C++):

#include <iostream>
#include <fstream>
#include <string>

struct TreeNode
{
   struct TreeNode* left;
   struct TreeNode* right;
   char  elem;
};

void BinaryTreeFromOrderings(char* inorder, char* preorder, int length)
{
    if(length == 0)
    {
       //cout<<"invalid length";
       return;
    }
    TreeNode* node = new TreeNode;//Noice that [new] should be written out.
    node->elem = *preorder;
    int rootIndex = 0;
    for(;rootIndex < length; rootIndex++)
    {
        if(inorder[rootIndex] == *preorder)
           break;
    }
    //Left
    BinaryTreeFromOrderings(inorder, preorder +1, rootIndex);
    //Right
    BinaryTreeFromOrderings(inorder + rootIndex + 1, preorder + rootIndex + 1, length - (rootIndex + 1));
    cout<<node->elem<<endl;
    return;
}

int main(int argc, char* argv[])
{
    printf("Hello World!\n");
    char* pr="GDAFEMHZ";
    char* in="ADEFGHMZ";

    BinaryTreeFromOrderings(in, pr, 8);

    printf("\n");
    return 0;
}

接着,是第二种情况的代码(代码C):

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef char TElemType;
#define MAX_TREE_SIZE 100

typedef struct BiTNode  //结点结构
{
    TElemType data; //结点数据
    struct BiTNode *lchild, *rchild;    //左右孩子指针
} BiTNode, *BiTree;

//建树并前序遍历
void BinaryTreeFromOrderings(char *mid, char *last, int len)
{
    //长度为0则返回空
    if (len == 0)
    {
        return ;
    }
    BiTree node = (BiTree)malloc(sizeof(BiTNode));  //分配结点空间
    node->data = last[len - 1];
    //mid中寻找根结点
    int rootIndex = 0;
    for (; rootIndex < len; rootIndex++)
    {
        if (mid[rootIndex] == last[len - 1])
        {
            break;
        }
    }
    //前序遍历,则在建一个节点打印一次
    printf("%c", node->data);
    //Left
    BinaryTreeFromOrderings(mid, last, rootIndex);
    //Right
    BinaryTreeFromOrderings(mid + rootIndex + 1, last + rootIndex, len - (rootIndex + 1));  //后段为右子树
    return ;
}

int main(int argc, const char * argv[])
{
    char mid[100], last[100], len;
    scanf("%s %s", mid, last);
    len = (int)strlen(mid);

    BinaryTreeFromOrderings(mid, last, len);

    printf("\n");
    return 0;
}

这两种情况算法都是一样的,差别就在于序列切割的位置不同,切割的方式也不同,也就是存在细节上的一些问题需要多注意才是,其他的就没有什么了,对了,要多学学怎么用指针,没有过硬的指针使用基础,会很不好做的,毕竟是数据结构中的知识,��。

全部评论

相关推荐

hso_:哈哈哈哈哈哈我没offer一样在同一道题开喷了
投递深圳同为数码等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享
正在热议
# 25届秋招总结 #
442240次浏览 4509人参与
# 春招别灰心,我们一人来一句鼓励 #
41913次浏览 531人参与
# 北方华创开奖 #
107423次浏览 599人参与
# 地方国企笔面经互助 #
7961次浏览 18人参与
# 同bg的你秋招战况如何? #
76585次浏览 561人参与
# 虾皮求职进展汇总 #
115499次浏览 886人参与
# 阿里云管培生offer #
120215次浏览 2219人参与
# 实习,投递多份简历没人回复怎么办 #
2454609次浏览 34856人参与
# 实习必须要去大厂吗? #
55761次浏览 961人参与
# 提前批简历挂麻了怎么办 #
149889次浏览 1977人参与
# 投递实习岗位前的准备 #
1195913次浏览 18548人参与
# 你投递的公司有几家约面了? #
33203次浏览 188人参与
# 双非本科求职如何逆袭 #
662189次浏览 7394人参与
# 如果公司给你放一天假,你会怎么度过? #
4751次浏览 55人参与
# 机械人春招想让哪家公司来捞你? #
157622次浏览 2267人参与
# 如果你有一天可以担任公司的CEO,你会做哪三件事? #
11535次浏览 284人参与
# 发工资后,你做的第一件事是什么 #
12682次浏览 62人参与
# 工作中,努力重要还是选择重要? #
35793次浏览 384人参与
# 参加完秋招的机械人,还参加春招吗? #
20120次浏览 240人参与
# 我的上岸简历长这样 #
452000次浏览 8088人参与
# 实习想申请秋招offer,能不能argue薪资 #
39289次浏览 314人参与
# 非技术岗是怎么找实习的 #
155866次浏览 2120人参与
牛客网
牛客企业服务