给出二叉树的先序遍历和中序遍历,请你输出它的后序遍历

题目描述

1、给定一棵二叉树的先序和中序序列,以单个字母表示一个节点,用一个字符串表示的一种序列,构造该二叉树。
2、采用后序遍历,输出后序遍历结果。
3、输入与输出字符之间没有空格或其它字符。

相关数据结构的一些简单算法

先序遍历

void PreOrderTraverse(BiTree T){
    if(T==NULL){
        return;
    }
    printf("%c",T->data);
    PostOrderTraverse(T->lchild);//先遍历左子树
    PostOrderTraverse(T->rchild);//在遍历右子树
    

中序遍历

void InOrderTraverse(BiTree T){
    if(T==NULL){
        return;
    }
    PostOrderTraverse(T->rchild);//在遍历右子树
    PostOrderTraverse(T->lchild);//先遍历左子树
   
    printf("%c",T->data);

后序遍历

void PostOrderTraverse(BiTree T){
    if(T==NULL){
        return;
    }
    PostOrderTraverse(T->lchild);//先遍历左子树
    PostOrderTraverse(T->rchild);//在遍历右子树
    printf("%c",T->data);
}

相关的遍历在代码上只是顺序不同

我一般这样记:先序:根左右,中序左根右,后序:左右根

本题思路分析

我们已经知道先序遍历和中序遍历,我们便可以唯一确定一颗二叉树,并可以还原该二叉树,并通过上文提及的递归公式获得后序遍历,我们关键是需要还原二叉树

BiTree  restoreTree(char pre[], char in[], int n)
{
    int i;
    char lpre[60], rpre[60];
    char lin[60], rin[60];
    int n1 = 0, n2 = 0;//n1记录前序遍历序列的左子树长度,n2则记录前序遍历序列的右子树长度
    int m1 = 0, m2 = 0;//m1记录中序遍历序列的左子树长度,m2记录中序遍历序列右子树长度
    if (n == 0)
    {
        return NULL;
    }
    BiTree T = (BiTree)malloc(sizeof(struct BiTNode));//创立节点
    T->data = pre[0];                    // 当前根节点
    for (i = 0; i < n; i++)
    {
        if (i <= n1 && in[i] != pre[0])
        {                                 //中序遍历被根节点分开的左子树的点
            lin[n1++] = in[i];//获得中序遍历的左子树
        }
        else if (in[i] != pre[0])
        {                                 //右子树的点,注意是else if,因为这个时候i是大于n1的
            rin[n2++] = in[i];
        }
    }
    //分前序遍历序列,注意!这里从1开始循环,因为0号元素作为根
    for (i = 1; i < n; i++)
    {
        if (i<(n1 + 1))               // 这里n1+1是因为编号是从1开始的,共有n1个左子树
        {
            lpre[m1++] = pre[i];
        }
        else
        {
            rpre[m2++] = pre[i];     //  其余为右子树
        }
    }
    T->lchild = restoreTree(lpre, lin, n1);
    T->rchild = restoreTree(rpre, rin, n2);
    //通过若干次递归最后实现二叉树的还原
    return T;
}

完整代码

```c
#include
#include "stdlib.h"
#include "string.h"
//二叉树的二叉链表结构
typedef struct BiTNode{
    char data;
    struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;
char pre_string[30];
char in_string[30];
BiTree  restoreTree(char pre[], char in[], int n)
{
    int i;
    char lpre[60],rpre[60];
    char lin[60],rin[60];
    int n1,n2;
    n1=n2=0;
    int m1=0,m2=0;
    if(n==0){
        return NULL;
    }
    BiTree T=(BiTree)malloc(sizeof(struct BiTNode));
    T->data=pre[0];
    for(i=0;i<n;i++){
        if(i<=n1&&in[i]!=pre[0]){
            lin[n1++]=in[i];
        }
        else if(in[i]!=pre[0]){
            rin[n2++]=in[i];
        }
    }
    for(i=1;i<n;i++){
        if(i<n1+1){
            lpre[m1++]=pre[i];
        }
        else{
            rpre[m2++]=pre[i];
        }
    }
    T->lchild=restoreTree(lpre,lin,n1);
    T->rchild=restoreTree(rpre,rin,n2);
    return T;
}
//后续遍历
void PostOrderTraverse(BiTree T){
    if(T==NULL){
        return;
    }
    PostOrderTraverse(T->lchild);//先遍历左子树
    PostOrderTraverse(T->rchild);//在遍历右子树
    printf("%c",T->data);
}
int main(){
    BiTree T;
    T=NULL;
    printf("please input The result of the traversal in order:");
    gets(pre_string);
    printf("please input The result of the traversal in preorder:");
    gets(in_string);
    int n=strlen(in_string);
    T=restoreTree(pre_string,in_string,n);
    PostOrderTraverse(T);
}

你可能感兴趣的:(数据结构,二叉树,数据结构,字符串)