满二叉树先序、中序、后序的相互转化

满二叉树先序、中序、层序遍历方式的相互转化,知一求二

这阵子要重学树,找了一些树的题目做做。比如下面这道满二叉树三种遍历方式
的相互转化,代码来自满二叉树先序、中序和后序之间的转换,我做说明与注释。为了便于实现,全部采用了树的顺序存储结构。

其实思想都是一样的,确定左右子树的下标位置,依次递归遍历每个子树,每次都选定根节点进行赋值。

下面分块说明。

  1. 先序转后序/后序转先序
    tmp:满二叉树先序遍历首尾节点的差的平均数,可知即为先序遍历时左子树的最后一个节点。
    后序转先序,看的出逻辑差不多,只是把已知和未知换了个位置,post变成了已知,pre变成了未知。
//先序序列转换为后序序列
//参数说明:  (in)   pre       ————  先序数组
//           (out)  post      ————  后序数组
//           (in)   preLow    ————  先序的第一个结点的下标
//           (in)   preHigh   ————  先序的最后一个结点的下标
//           (in)   postLow   ————  后序的第一个结点的下标
//           (in)   postHigh  ————  后序的最后一个结点的下标
void PreToPost(int pre[], int post[], int preLow, int preHigh, int postLow, int postHigh)
{
    if (preHigh >= preLow)
    {
        post[postHigh] = pre[preLow];
        int tmp = (preHigh - preLow) / 2;
        PreToPost(pre, post, preLow + 1, preLow + tmp, postLow, postLow + tmp - 1);
        PreToPost(pre, post, preLow + tmp + 1, preHigh, postLow + tmp, postHigh - 1);
    }
}
//后序序列转换为先序序列
//参数说明:  (out)  pre       ————  先序数组
//           (in)   post      ————  后序数组
//           (in)   preLow    ————  先序的第一个结点的下标
//           (in)   preHigh   ————  先序的最后一个结点的下标
//           (in)   postLow   ————  后序的第一个结点的下标
//           (in)   postHigh  ————  后序的最后一个结点的下标
void PostToPre(int pre[], int post[], int preLow, int preHigh, int postLow, int postHigh)
{
    if (postHigh >= postLow)
    {
        pre[preLow] = post[postHigh];
        int tmp = (postHigh - postLow) / 2;
        PostToPre(pre, post, preLow + 1, preLow + tmp, postLow, postLow + tmp - 1);
        PostToPre(pre, post, preLow + tmp + 1, preHigh, postLow + tmp, postHigh - 1);
    }
}
  1. 先序转中序/中序转先序
    同理.
//先序序列转换为中序序列
//参数说明:  (in)  pre       ————  先序数组
//           (out)  mid       ————  中序数组
//           (in)   preLow    ————  先序的第一个结点的下标
//           (in)   preHigh   ————  先序的最后一个结点的下标
//           (in)   midLow    ————  中序的第一个结点的下标
//           (in)   midHigh   ————  中序的最后一个结点的下标
void PreToMid(int pre[], int mid[], int preLow, int preHigh, int midLow, int midHigh)
{
    if (preHigh >= preLow)
    {
        mid[(midHigh + midLow) / 2] = pre[preLow];
        int tmp = (preHigh - preLow) / 2;
        PreToMid(pre, mid, preLow + 1, preLow + tmp, midLow, midLow + tmp - 1);
        PreToMid(pre, mid, preLow + tmp + 1, preHigh, midLow + tmp + 1, midHigh);
    }
}

//中序序列转换为先序序列
//参数说明:  (out)  pre       ————  先序数组
//           (in)   mid       ————  后序数组
//           (in)   preLow    ————  先序的第一个结点的下标
//           (in)   preHigh   ————  先序的最后一个结点的下标
//           (in)   midLow    ————  中序的第一个结点的下标
//           (in)   midHigh   ————  中序的最后一个结点的下标
void MidToPre(int pre[], int mid[], int preLow, int preHigh, int midLow, int midHigh)
{
    if (midHigh >= midLow)
    {
        int tmp = (midHigh - midLow) / 2;
        pre[preLow] = mid[(midHigh + midLow) / 2];
        MidToPre(pre, mid, preLow + 1, preLow + tmp, midLow, midLow + tmp - 1);
        MidToPre(pre, mid, preLow + tmp + 1, preHigh, midLow + tmp + 1, midHigh);
    }
}
  1. 后序转中序/中序转后序
//后序序列转换为中序序列
//参数说明:  (in)  post       ————  后序数组
//           (out)  mid       ————  中序数组
//           (in)   postLow   ————  后序的第一个结点的下标
//           (in)   postHigh  ————  后序的最后一个结点的下标
//           (in)   midLow    ————  中序的第一个结点的下标
//           (in)   midHigh   ————  中序的最后一个结点的下标
void PostToMid(int post[], int mid[], int midLow, int midHigh, int postLow, int postHigh)
{
    if (postHigh >= postLow)
    {
        mid[(midHigh + midLow) / 2] = post[postHigh];
        int tmp = (postHigh - postLow) / 2;
        PostToMid(post, mid, midLow, midLow + tmp - 1, postLow, postLow + tmp - 1);
        PostToMid(post, mid, midLow + tmp + 1, midHigh, postLow + tmp, postHigh - 1);
    }
}

//中序序列转换为后序序列
//参数说明:  (out)  post      ————  后序数组
//           (in)   mid       ————  中序数组
//           (in)   postLow   ————  后序的第一个结点的下标
//           (in)   postHigh  ————  后序的最后一个结点的下标
//           (in)   midLow    ————  中序的第一个结点的下标
//           (in)   midHigh   ————  中序的最后一个结点的下标
void MidToPost(int post[], int mid[], int midLow, int midHigh, int postLow, int postHigh)
{
    if (midHigh >= midLow)
    {
        post[postHigh] = mid[(midHigh + midLow) / 2];
        int tmp = (midHigh - midLow) / 2;
        MidToPost(post, mid, midLow, midLow + tmp - 1, postLow, postLow + tmp - 1);
        MidToPost(post, mid, midLow + tmp + 1, midHigh, postLow + tmp, postHigh - 1);
    }
}

下面是原代码。

#include 
using namespace std;

//*****************************满二叉树先序、中序和后序之间的转换*****************************begin

//先序序列转换为后序序列
//参数说明:  (in)   pre       ————  先序数组
//           (out)  post      ————  后序数组
//           (in)   preLow    ————  先序的第一个结点的下标
//           (in)   preHigh   ————  先序的最后一个结点的下标
//           (in)   postLow   ————  后序的第一个结点的下标
//           (in)   postHigh  ————  后序的最后一个结点的下标
void PreToPost(int pre[], int post[], int preLow, int preHigh, int postLow, int postHigh)
{
    if (preHigh >= preLow)
    {
        post[postHigh] = pre[preLow];
        int tmp = (preHigh - preLow) / 2;
        PreToPost(pre, post, preLow + 1, preLow + tmp, postLow, postLow + tmp - 1);
        PreToPost(pre, post, preLow + tmp + 1, preHigh, postLow + tmp, postHigh - 1);
    }
}

//后序序列转换为先序序列
//参数说明:  (out)  pre       ————  先序数组
//           (in)   post      ————  后序数组
//           (in)   preLow    ————  先序的第一个结点的下标
//           (in)   preHigh   ————  先序的最后一个结点的下标
//           (in)   postLow   ————  后序的第一个结点的下标
//           (in)   postHigh  ————  后序的最后一个结点的下标
void PostToPre(int pre[], int post[], int preLow, int preHigh, int postLow, int postHigh)
{
    if (postHigh >= postLow)
    {
        pre[preLow] = post[postHigh];
        int tmp = (postHigh - postLow) / 2;
        PostToPre(pre, post, preLow + 1, preLow + tmp, postLow, postLow + tmp - 1);
        PostToPre(pre, post, preLow + tmp + 1, preHigh, postLow + tmp, postHigh - 1);
    }
}

//先序序列转换为中序序列
//参数说明:  (in)  pre       ————  先序数组
//           (out)  mid       ————  中序数组
//           (in)   preLow    ————  先序的第一个结点的下标
//           (in)   preHigh   ————  先序的最后一个结点的下标
//           (in)   midLow    ————  中序的第一个结点的下标
//           (in)   midHigh   ————  中序的最后一个结点的下标
void PreToMid(int pre[], int mid[], int preLow, int preHigh, int midLow, int midHigh)
{
    if (preHigh >= preLow)
    {
        mid[(midHigh + midLow) / 2] = pre[preLow];
        int tmp = (preHigh - preLow) / 2;
        PreToMid(pre, mid, preLow + 1, preLow + tmp, midLow, midLow + tmp - 1);
        PreToMid(pre, mid, preLow + tmp + 1, preHigh, midLow + tmp + 1, midHigh);
    }
}

//中序序列转换为先序序列
//参数说明:  (out)  pre       ————  先序数组
//           (in)   mid       ————  后序数组
//           (in)   preLow    ————  先序的第一个结点的下标
//           (in)   preHigh   ————  先序的最后一个结点的下标
//           (in)   midLow    ————  中序的第一个结点的下标
//           (in)   midHigh   ————  中序的最后一个结点的下标
void MidToPre(int pre[], int mid[], int preLow, int preHigh, int midLow, int midHigh)
{
    if (midHigh >= midLow)
    {
        int tmp = (midHigh - midLow) / 2;
        pre[preLow] = mid[(midHigh + midLow) / 2];
        MidToPre(pre, mid, preLow + 1, preLow + tmp, midLow, midLow + tmp - 1);
        MidToPre(pre, mid, preLow + tmp + 1, preHigh, midLow + tmp + 1, midHigh);
    }
}

//后序序列转换为中序序列
//参数说明:  (in)  post       ————  后序数组
//           (out)  mid       ————  中序数组
//           (in)   postLow   ————  后序的第一个结点的下标
//           (in)   postHigh  ————  后序的最后一个结点的下标
//           (in)   midLow    ————  中序的第一个结点的下标
//           (in)   midHigh   ————  中序的最后一个结点的下标
void PostToMid(int post[], int mid[], int midLow, int midHigh, int postLow, int postHigh)
{
    if (postHigh >= postLow)
    {
        mid[(midHigh + midLow) / 2] = post[postHigh];
        int tmp = (postHigh - postLow) / 2;
        PostToMid(post, mid, midLow, midLow + tmp - 1, postLow, postLow + tmp - 1);
        PostToMid(post, mid, midLow + tmp + 1, midHigh, postLow + tmp, postHigh - 1);
    }
}

//中序序列转换为后序序列
//参数说明:  (out)  post      ————  后序数组
//           (in)   mid       ————  中序数组
//           (in)   postLow   ————  后序的第一个结点的下标
//           (in)   postHigh  ————  后序的最后一个结点的下标
//           (in)   midLow    ————  中序的第一个结点的下标
//           (in)   midHigh   ————  中序的最后一个结点的下标
void MidToPost(int post[], int mid[], int midLow, int midHigh, int postLow, int postHigh)
{
    if (midHigh >= midLow)
    {
        post[postHigh] = mid[(midHigh + midLow) / 2];
        int tmp = (midHigh - midLow) / 2;
        MidToPost(post, mid, midLow, midLow + tmp - 1, postLow, postLow + tmp - 1);
        MidToPost(post, mid, midLow + tmp + 1, midHigh, postLow + tmp, postHigh - 1);
    }
}

//*****************************满二叉树先序、中序和后序之间的转换*****************************end

int main()
{
    int Pre[15] = {1, 2, 4, 8, 9, 5, 10, 11, 3, 6, 12, 13, 7, 14, 15};
    int PreChangeToMid[15] = {0};
    int PreChangeToPost[15] = {0};
    cout<<"**************************前序转换为中序**************************"<

你可能感兴趣的:(树算法,数据结构)