王道书 P150 T15(已知一棵树是满二叉树,已知先序序列求解后序序列)+ 拓展(已知一棵树是满二叉树,已知后序序列求解先序序列)

/**
 * 用二叉树链式存储实现 王道 P150 T15(已知一棵树是满二叉树,已知先序序列求解后序序列)+ 拓展(已知一棵树是满二叉树,已知后序序列求解先序序列)
 *
 * ①算法思想
 * 关于①:
 * 我们如果想要还原出一棵树,一定要有中序序列的参与,原因是中序序列可以确定左右子树的长度,
 * 但是此题只给了先序序列,没有给中序序列,怎么才能得到后序序列呢?
 * 注意到此题是满二叉树,满二叉树的序列长度一定是奇数,
 * 如果把满二叉树的先序序列长度除以二,就可以得到左右子树的长度,那么这样就起到了和中序序列一样的效果.
 * 我们平时的做法是先把树还原出来,然后再遍历一下得到需要的序列,
 * 但是此处,我们可以直接通过先序序列得到后序序列,跳过还原树和遍历的过程。
 * 此题就相当于我们在中序序列中知道了左右子树的长度,然后不断地缩小左右子树范围,执行post[r2] = pre[l1];,一步一步去还原。
 * 关于②:
 * 同理。
 *
 * ②算法设计
 */


#include 
#include 
#define MaxSize 100

typedef struct BiTreeNode{
    int data;
    BiTreeNode *lchild,*rchild;
}BiTreeNode,*BiTree;


//P150 T15
//①已知一棵树是满二叉树,已知先序序列求解后序序列
void PreToPost(int pre[],int l1,int r1,int post[],int l2,int r2){//l1、r1表示后序序列的最左端和最右端,l2、r2表示先序序列的最左端和最右端
    if(l1 > r1)
        return;//不断地缩小左右子树范围,当l1>r1的时候,就说明结束了
    post[r2] = pre[l1];
    int half = (r1 - l1) / 2;//先序序列长度的一半,也就是左子树序列长度和右子树序列长度
    PreToPost(pre,l1 + 1,l1 + half,post,l2,l2 + half - 1);//锁定左子树在先序序列中的范围和在后序序列中的范围
    PreToPost(pre,r1 - half + 1,r1,post,r2 - half,r2 - 1);//锁定右子树在先序序列中的范围和在后序序列中的范围
}
//②已知一棵树是满二叉树,已知后序序列求解先序序列
void PostToPre(int post[],int l1,int r1,int pre[],int l2,int r2){//l1、r1表示后序序列的最左端和最右端,l2、r2表示先序序列的最左端和最右端
    if(l1 > r1)
        return;//不断地缩小左右子树范围,当l1>r1的时候,就说明结束了
    pre[l2] = post[r1];
    int half = (r1 - l1) / 2;//后序序列长度的一半,也就是左子树序列长度和右子树序列长度
    PostToPre(post,l1,l1 + half - 1,pre,l2 + 1,l2 + half);//锁定左子树在后序序列中的范围和在先序序列中的范围
    PostToPre(post,r1 - half,r1 - 1,pre,r2 - half + 1,r2);//锁定右子树在后序序列中的范围和在先序序列中的范围
}

王道书 P150 T15(已知一棵树是满二叉树,已知先序序列求解后序序列)+ 拓展(已知一棵树是满二叉树,已知后序序列求解先序序列)_第1张图片
王道书 P150 T15(已知一棵树是满二叉树,已知先序序列求解后序序列)+ 拓展(已知一棵树是满二叉树,已知后序序列求解先序序列)_第2张图片

你可能感兴趣的:(王道书第五章综合应用题,算法,c++,数据结构,c语言,链表)