已知二叉树的先序和中序求后序遍历

已知二叉树的先序和中序求后序遍历
二叉树的遍历算法在其他树操作的基础
已知先序和中序求二叉树的后序遍历算法核心是
1、从先序遍历中读入根节点
2、从中序遍历中找到与根节点相等的元素,以此节点将中序序列分成两个部分,左边的为二叉树的
左子树,右边为二叉树的右子树;
3、递归调用上述步骤得到根节点的左、右子树

 

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

#define MAXN 55

int idx;
char pre[MAXN],in[MAXN],post[MAXN];

int findpos(char key,char *str,int s,int e)
{
    int i;
    for(i=s;i<=e;i++)
        if(key == str[i]) break;
    return i;
}

void solve(int ps,int pe,int is,int ie)
{
    if(ps > pe || is > ie) return;
    if(is == ie)
    {
        post[idx++] = in[is];
        return;
    }
    int k = findpos(pre[ps],in,is,ie);
    solve(ps+1,ps-is+k , is,k-1);
    solve(ps-is+k+1,pe , k+1,ie);
    post[idx++]=pre[ps];
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("tdata.txt","r",stdin);
    #endif
    while(scanf("%s",pre)!=EOF)
    {
        scanf("%s",in);
        idx=0;
        solve(0,strlen(pre)-1,0,strlen(in)-1);
        post[idx]=0;
        printf("%s\n",post);
    }
    return 0;
}


在C语言中,如果你已经知道了二叉树先序遍历(Preorder Traversal)和中序遍历(Inorder Traversal),可以通过这两个序列重构出后序遍历(Postorder Traversal)。这是因为对于任何一个节点,它的后序遍历顺序通常是左子树 -> 右子树 -> 节点本身。 首先,我们需要三个指针分别表示当前节点、前驱节点和待访问的左子树。后序遍历的算法步骤如下: 1. 初始化后序遍历结果数组 `postorder` 和长度 `size`。 2. 使用先序遍历构建线索(即通过第一个元素找到根节点): - 先序遍历的第一个元素作为根节点的线索。 3. 对于线索所指的节点,递归地处理左子树和右子树: - 如果线索指向的是左子节点,那么它就是后序遍历中的下一个节点,将其添加到 `postorder` 并更新线索到下一个元素。 - 如果线索指向的是右子节点,那么需要先完成左子树的后序遍历,然后继续这个右子节点。 4. 当线索为空时,说明已经处理完了当前节点及其所有子节点,将当前节点添加到 `postorder` 的最后一位,并返回 `size`。 5. 最终 `postorder[0:size-1]` 就是后序遍历的结果。 以下是一个简单的C语言实现示例: ```c #include <stdio.h> typedef struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; } TreeNode; // 从先序遍历和中序遍历构造后序遍历 void buildPostorder(int preorder[], int inorder[], TreeNode* root, int size, int *postorder, int postSize) { if (root == NULL || size <= 0) return; // 找到根节点在中序遍历中的位置 for (int i = 0; i < size && inorder[i] != root->val; i++) ; // 递归处理左右子树 buildPostorder(preorder, inorder, root->left, i, postorder, postSize); buildPostorder(preorder + i + 1, inorder + i + 1, root->right, size - (i + 1), postorder, postSize); // 将根节点添加到后序遍历的末尾 postorder[postSize++] = preorder[size - 1]; } int main() { // 示例输入:先序遍历 [1, 2, 4, 5, 3, 6] // 中序遍历 [4, 2, 5, 1, 3, 6] int preorder[] = {1, 2, 4, 5, 3, 6}; int inorder[] = {4, 2, 5, 1, 3, 6}; int size = sizeof(preorder) / sizeof(preorder[0]); int postSize = 0; TreeNode* root = createTreeFromPreAndInOrder(preorder, inorder); // 根据给定的先序中序创建二叉树 int postorder[size]; // 后序遍历结果数组 buildPostorder(preorder, inorder, root, size, postorder, &postSize); // 输出后序遍历结果 for (int i = 0; i < postSize; i++) { printf("%d ", postorder[i]); } return 0; } ``` 注意,这里假设有一个 `createTreeFromPreAndInOrder` 函数用于根据给定的先序遍历和中序遍历构建二叉树,你需要自定义这个函数。此外,上述代码未包含错误处理和边界条件检查,实际应用时请确保适当增加。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值