二叉树:已知先序和中序求后序,已知中序和后序求先序

树的三种遍历方式的遍历顺序:
先序遍历:根、左子树、右子树(特点:第一个元素为根)
中序遍历:左子树、根、右子树(特点:根的两边分别为左子树和右子树)
后序遍历:左子树、右子树、根(特点:最后一个元素为根)
有如下图的二叉树:
其先序、中序、后序遍历分别为:DBACEGF、ABCDEFG、ACBFGED。
1、已知先序和中序求后序
先序遍历的第一个字符为根,因此只需在中序遍历中找到它,就可以把根节点的左子树和右子树分开,就可以知道左子树的字符个数和右子树的字符个数,然后可以确定先序遍历中哪部分是左子树,哪部分是右子树,之后递归先序遍历的序列,直到结束。
如上面的例子:先序遍历的第一个字符是D,则根节点为D,从中序遍历中可以找到D的位置,左边的ABC即为左子树的字符,右边的EFG即为右子树的字符,如果开始递归函数为:build(“DBACEGF”),则找到根的位置后,可以分为递归左子树的先序遍历和递归右子树的先序遍历:build(“BAC”)和build(“EFG”),其对应的中序遍历为:ABC和EFG。然后继续进行以上步骤,直到找完先序序列。每找到根就可以直接输出或保存到数组中,需要注意的是递归的时候不要把根包含在内。
代码如下(已知先序和中序求后序):

#include<stdio.h>
#include<cstring>
char a[30],b[30];
void fun(int r1, int l1, int r2, int l2)
{{//四个参数分别为:先序遍历的起始位置和结束位置和中序遍历的起始位置和结束位置
    int i;
    if(r1>l1))//如果已经到达叶子,返回
    return;
    for(i=r2;b[i]!=a[r1];++i);//找到根节点在中序遍历中的位置
    fun(r1+1, l1-l2+i,r2,i-1);//递归求左子树的后序遍历,r1+1是指把根去掉之后的位置
    fun(l1-l2+i+1,l1,i+1,l2);//递归求右子树的后序遍历
    putchar(a[r1]);//在递归结束后输出根
}
int main(void)
{
    int i;
    while(scanf("%s%s",a,b)!=EOF)
    {
        int l=strlen(a);
        fun(0,l-1,0,l-1);
        puts("");
    }
    return 0;
}

2、已知中序和后序求先序
后序序列的特点是最后一个是根,道理与已知先序和中序求后序一样,同样是递归,只是需要改变几个参数。附上代码和注释。

#include<stdio.h>
#include<cstring>
char a[30],b[30];
void fun(int r1, int l1, int r2, int l2)
{
    int i;
    if(r1>l1)
    return;
    putchar(a[l1]);//由于是求先序遍历,所以要先输出根节点
    for(i=r2;b[i]!=a[l1];++i);//对应的,后序序列的最后一个为根,所以根为a[l1]
    fun(r1,l1-l2+i-1,r2,i-1);//递归求左子树的先序遍历
    fun(l1-l2+i,l1-1,i+1,l2);//递归求右子树的先序遍历,l1-1为去掉根后的位置
}
int main(void)
{
    int i;
    while(scanf("%s%s",a,b)!=EOF)
    {//先输入后序,在输入中序
        int l=strlen(a);
        fun(0,l-1,0,l-1);
        puts("");
    }
    return 0;
}
可以使用递归的方式来实现先序中序后序,具体实现代码如下: ```java public class Tree { private static class Node { private char value; private Node left; private Node right; public Node(char value) { this.value = value; } } public static String preInToPost(String preOrder, String inOrder) { if (preOrder == null || inOrder == null || preOrder.length() != inOrder.length()) { return null; } Node root = preInToPost(preOrder.toCharArray(), 0, preOrder.length() - 1, inOrder.toCharArray(), 0, inOrder.length() - 1); StringBuilder sb = new StringBuilder(); postOrder(root, sb); return sb.toString(); } private static Node preInToPost(char[] preOrder, int preStart, int preEnd, char[] inOrder, int inStart, int inEnd) { if (preStart > preEnd) { return null; } Node root = new Node(preOrder[preStart]); int index = findIndex(inOrder, inStart, inEnd, preOrder[preStart]); int leftSize = index - inStart; root.left = preInToPost(preOrder, preStart + 1, preStart + leftSize, inOrder, inStart, index - 1); root.right = preInToPost(preOrder, preStart + leftSize + 1, preEnd, inOrder, index + 1, inEnd); return root; } private static void postOrder(Node root, StringBuilder sb) { if (root == null) { return; } postOrder(root.left, sb); postOrder(root.right, sb); sb.append(root.value); } private static int findIndex(char[] arr, int start, int end, char target) { for (int i = start; i <= end; i++) { if (arr[i] == target) { return i; } } return -1; } public static void main(String[] args) { String preOrder = "ABDCEGF"; String inOrder = "DBAEGCF"; String postOrder = preInToPost(preOrder, inOrder); System.out.println(postOrder); // DCBGEFA } } ``` 该代码中使用了一个内部类 `Node` 表示二叉树的节点,`preInToPost` 方法用于递归构建二叉树,`postOrder` 方法用于递归遍历二叉树并输出后序遍历序列,`findIndex` 方法用于查找中序遍历序列中某个元素的位置。最后在 `main` 方法中调用 `preInToPost` 方法并输出结果。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值