二叉树——由中根序列和后根序列重建二叉树

本文介绍了一种通过中根和后根序列重建二叉树的方法,并最终输出其前根序列。利用递归算法实现从序列到树的转换,进而展示了树遍历的不同顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接
总时间限制: 500ms 内存限制: 65535kB
描述
我们知道如何按照三种深度优先次序来周游一棵二叉树,来得到中根序列、前根序列和后根序列。反过来,如果给定二叉树的中根序列和后根序列,或者给定中根序列和前根序列,可以重建一二叉树。本题输入一棵二叉树的中根序列和后根序列,要求在内存中重建二叉树,最后输出这棵二叉树的前根序列。

用不同的整数来唯一标识二叉树的每一个结点

中根序列是9 5 32 67

后根序列9 32 67 5

前根序列5 9 67 32

输入
两行。第一行是二叉树的中根序列,第二行是后根序列。每个数字表示的结点之间用空格隔开。结点数字范围0~65535。暂不必考虑不合理的输入数据。
输出
一行。由输入中的中根序列和后根序列重建的二叉树的前根序列。每个数字表示的结点之间用空格隔开。
样例输入

9 5 32 67
9 32 67 5

样例输出

5 9 67 32

关键在于利用通过后序找到每个子树的根节点,以此为界找到左、右子树,从而进行递归。
链式算法

#include <cstdio>
#include <cstdlib>
#include <cstring>
#define N 65536

typedef struct node{
    int data;
    struct node * lc,*rc;
}BitNode,*BitTree;

int sLDR[N],sLRD[N];


BitTree BuildTree(int coStart,int coEnd,int loStart, int loEnd){
    BitTree root = (BitTree)malloc(sizeof(BitNode));
    root->data = sLRD[loEnd];
    root->lc = NULL;
    root->rc = NULL;
    int i;

    if(coStart == coEnd)
        return root;
    for(i = 0;i <= coEnd-coStart;i++){
        if(sLDR[coStart+i] == sLRD[loEnd])
            break;
    }

    if(i>=1) root->lc = BuildTree(coStart,coStart+i-1,loStart,loStart+i-1);
    if(coEnd>=coStart+i+1) root->rc = BuildTree(coStart+i+1,coEnd,loStart+i,loEnd-1);
    return root;
}

int visit(BitTree T){
    printf("%d ",T->data);
    return T->data;
}

int PreTranverse(BitTree T){
    if(T){
        visit(T);
        if(T->lc)
            PreTranverse(T->lc);
        if(T->rc)
            PreTranverse(T->rc);
    }
    return 1;
}

int main(){
    //freopen("in.txt","r",stdin);
    int s[N];
    int order = 0;
    int ch;
    while((scanf("%d",&ch))!=EOF){
        s[++order] = ch;
    }
    for(int i = 1;i <= order/2;i++)
        sLDR[i] = s[i];
    for(int i = 1;i <= order/2;i++)
        sLRD[i] = s[order/2+i];
    BitTree root = BuildTree(1,order/2,1,order/2);
    PreTranverse(root);
    printf("\n");
    return 0;
}

顺序算法

#include <cstdio>
#include <cstdlib>
#include <cstring>
#define N 65536

typedef struct node{
    int data;
    struct node * lc,*rc;
}BitNode,*BitTree;

int sLDR[N],sLRD[N];
int tree[N];


void BuildTree(int coStart,int coEnd,int loStart, int loEnd,int k){
    //BitTree root = (BitTree)malloc(sizeof(BitNode));
    tree[k] = sLRD[loEnd];
    tree[2*k] = 0;
    tree[2*k+1] = 0;
    //root->lc = NULL;
    //root->rc = NULL;
    int i;

    if(coStart == coEnd)
        return ;
    for(i = 0;i <= coEnd-coStart;i++){
        if(sLDR[coStart+i] == sLRD[loEnd])
            break;
    }

    if(i>=1) BuildTree(coStart,coStart+i-1,loStart,loStart+i-1,2*k);
    if(coEnd>=coStart+i+1) BuildTree(coStart+i+1,coEnd,loStart+i,loEnd-1,2*k+1);
    //return root;
}

int visit(int i){
    printf("%d ",tree[i]);
    return tree[i];
}

int PreTranverse(int i){
    if(tree[i]){
        visit(i);
        if(tree[2*i])
            PreTranverse(2*i);
        if(tree[2*i+1])
            PreTranverse(2*i+1);
    }
    return 1;
}

int main(){
    //freopen("in.txt","r",stdin);
    int s[N];
    int order = 0;
    int ch;
    while((scanf("%d",&ch))!=EOF){
        s[++order] = ch;
    }
    for(int i = 1;i <= order/2;i++)
        sLDR[i] = s[i];
    for(int i = 1;i <= order/2;i++)
        sLRD[i] = s[order/2+i];
    BuildTree(1,order/2,1,order/2,1);
    PreTranverse(1);
    printf("\n");
    return 0;
}

转载于:https://www.cnblogs.com/sean10/p/4986862.html

在C语言中,如果你知道了二叉树的后序遍历(Postorder Traversal,即左->右->序列中序遍历(Inorder Traversal,即左->->右)序列,你可以利用这两个序列来重构原来的二叉树。这是因为对于任何二叉树,其后序遍历的结果包含了所有节点的信息,而中序遍历可以告诉你每个节点的位置。 下面是基本步骤: 1. **理解两个序列**: - 后序遍历序列:用于确定每个节点在重构后的顺序,其中最后一个元素是节点。 - 中序遍历序列:用于确定每个节点的左子树右子树,因为它按照左->->右的顺序访问。 2. **查找节点**: - 后序遍历序列中最后一个元素是节点。 3. **划分左右子树**: - 对于节点,从中序遍历序列中找到它的位置,左边的部分是左子树的中序序列,右边的部分是右子树的中序序列。 4. **递归构建子树**: - 使用相同的算法对左子树右子树分别进行递归,直到遍历完所有节点。 5. **创建二叉树结构**: - 据找到的子树中序序列,创建对应的二叉树结构,并将子树连接到父节点。 C语言中实现这个功能的具体代码会涉及到递归,可能会用到链表或者栈来辅助存储中间结果。由于这里是一个文本环境,我无法展示完整的代码,但你可以参考类似的数据结构算法教程来实现这个功能。 ```c typedef struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; } TreeNode; // 函数原型 TreeNode* buildTree(int post[], int size, int in[], int inorderSize); // 递归实现 TreeNode* buildTree(int post[], int size, int in[], int inorderSize) { if (inorderSize == 0) return NULL; // 当中序序列为空时,结束当前层级 TreeNode* root = new TreeNode(post[size - 1]); // 节点 int index = search(in, inorderSize, post[size - 1]); // 找到节点在中序序列中的位置 root->left = buildTree(post, size - 1 - index, in, index); // 构建左子树 root->right = buildTree(post, size - 1, in + index, inorderSize - index - 1); // 构建右子树 return root; } int search(int arr[], int size, int target) { /* 中序序列搜索函数 */ // ... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值