《编程之美》——重建二叉树

问题:
已知二叉树的前序中序遍历结果,重建二叉树。

分析与解法:

  • 初始:用前序遍历序列确定根节点,在中序遍历序列中找到该根节点,则左右子树分别为中序中该节点左右的序列。
  • 迭代:对各个子树分别执行三步操作,1.在前序序列中找子树的根节点;2。在中序序列中找子树的根节点,并划分开根节点的左右子树;3.根据新生成的左右子树,在前序序列中划分开这些节点,从而得到了两颗子树的前序、中序序列。

代码:

typedef struct Node
{
    struct Node *lchild, *rchild;//指向左右子树的指针
    char cdata;                  //节点数值
}Node, *BiTree;

//前序+中序
void rePreInBuild(BiTree &T,//重建的二叉树
              char *preOrder,//前序遍历序列
              char *inOrder, //中序遍历序列
              int n)         //二叉树的节点个数
{
    //判断边界条件
    if(preOrder == NULL || inOrder == NULL || n == 0)
        return;

    //获取根节点
    T = new Node;
    T -> cdata = *preOrder;
    T -> lchild = NULL;
    T -> rchild = NULL;

    //查找根节点在中序遍历序列中的位置
    int i;
    for(i = 0; i < n && *(inOrder + i) != T -> cdata; i++);

    int llen = i;//左子树节点的个数
    int rlen = n - i - 1;//右子树节点的个数

    if(llen > 0)//重建左子树
        rePreInBuild(T -> lchild, preOrder + 1, inOrder, llen);
    if(rlen > 0)//重建右子树
        rePreInBuild(T -> rchild, preOrder + llen + 1, inOrder + llen + 1, rlen);
}

思考:
已知二叉树的后序中序遍历结果,重建二叉树。解法同上。
已知二叉树的层序中序遍历结果,重建二叉树。

  • 初始:用层序遍历确定顶节点,在中序遍历中,利用顶节点划分出左右子树。
  • 迭代:对各个子树分别执行三步操作,1.在层序序列中,找出子树节点集合中,最靠前的节点,这个节点即为子树的顶节点;2.在中序序列中找 1 中得到的顶节点,并划分开顶节点的左右子树。
  • 跟(中序+前序)和(中序+后序)不同.之处在于没有迭代的第 3 步,层序是无法直接划分得到左右子树的节点集合的。但这并不妨碍正常的处理。层序是用来找到子树的顶节点的,而顶节点即是所有子树的节点中,在层序遍历中最靠前的节点。

代码:

//后序+中序
void rePostInBuild(BiTree &T, char *postOrder, char *inOrder, int n)
{
    if(postOrder == NULL || inOrder == NULL || n == 0)
        return;

    T = new Node;
    T -> cdata = *(postOrder + n - 1);
    T -> lchild = NULL;
    T -> rchild = NULL;

    int i;
    for(i = 0; i < n && *(inOrder + i) != T -> cdata; i++);

    int llen = i;
    int rlen = n - i - 1;

    if(llen > 0)
         rePostInBuild(T -> lchild, postOrder, inOrder, llen);
    if(rlen > 0)
         rePostInBuild(T -> rchild, postOrder + llen, inOrder + llen + 1, rlen);
}

扩展问题:

  1. 如果前序和中序遍历的字母有重复的,那么怎么构造所有可能的解呢?
  2. 如何判断给定的前序遍历和中序遍历的结果是合理的?

http://blog.csdn.net/vividonly/article/details/6688327

文章参考以下博文:
http://blog.csdn.net/luyafei_89430/article/details/12967411
http://blog.csdn.net/yunzhongguwu005/article/details/9270085

    原文作者:zengzhen_csdn
    原文地址: https://blog.csdn.net/zengzhen_CSDN/article/details/49822421
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞