二叉树重建(一)

原创 2015年11月21日 20:09:39

问题描述

二叉树重建(根据先序遍历和中序遍历获取二叉树的后序遍历)。

主要算法

重新建树算法:先序序列的第一个元素为二叉树的根,通过根和中序序列可以将二叉树分为左子树、根、右子树三部分(左子树、右子树可能为空)。根据第二个元素又可以将二叉树的左子树或者右子树(左子树为空的情况下)分成更小左子树、根、右子树。如此下去,依次利用先序序列中的元素将子树划分成更小的子树。

二叉树已经重建完毕,要获取后序遍历序列也就不难了,只需对二叉树进行后序遍历既可。

代码

/*
功能:二叉树重建(根据先序遍历和中序遍历获取二叉树的后序遍历)
作者:pussy
日期:2015-11-21
*/

# include<stdio.h>
# include<malloc.h>
# include<string.h>
# define MAX 100

char pre[MAX];
int i=0;

typedef struct BiTNode{
    char data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

typedef struct{
    BiTree data[MAX];
    int top;
}Stack;

void build(char in[],int left,int right,BiTree &T);
BiTree newnode(char c);
int getIndex(char in[],char c);
void PostOrder(BiTree T,Stack s1,Stack s2);
void InitStack(Stack &s);
int isFull(Stack s);
int isEmpty(Stack s);
int Push(Stack &s,BiTree t);
int Pop(Stack &s);
int getTop(Stack &s,BiTree &t);

int main()
{
    printf("请依次输入二叉树的先序和中序遍历序列\n");
    char in[MAX];
    scanf("%s%s",pre,in);
    BiTree T=NULL;
    Stack s1,s2;
    InitStack(s1);
    InitStack(s2);
    build(in,0,strlen(in)-1,T);
    printf("后序遍历序列为:\n");
    PostOrder(T,s1,s2);
    printf("\n");
    return 0;
}

//根据先序和中序遍历序列重建二叉树
void build(char in[],int left,int right,BiTree &T)
{
    if(left>right)//空子树
    {
        //T=NULL;
        return ;
    }
    else if(left==right)
    {
        T=newnode(pre[i++]);//叶子节点
        return ;
    }
    else
    {
        T=newnode(pre[i]);
        int r=getIndex(in,pre[i++]);
        build(in,left,r-1,T->lchild);
        build(in,r+1,right,T->rchild);
    }
}

//分配一个新的节点
BiTree newnode(char c)
{
    BiTree t=(BiTree)malloc(sizeof(BiTNode));
    t->data=c;
    t->lchild=t->rchild=NULL;
    return t;
}

//获取字符在字符串中的下标
int getIndex(char in[],char c)
{
    int j;
    for(j=0;j<strlen(in);j++)
    {
        if(in[j]==c)
            return j;
    }
    return j;
}

void PostOrder(BiTree T,Stack s1,Stack s2)
{
    BiTree t=T;
    Push(s1,t);Push(s2,t);
    while(!isEmpty(s1))
    {
        while(t!=NULL)
        {
            Push(s1,t->rchild);
            if(t->rchild)
                Push(s2,t->rchild);
            t=t->rchild;
        }   
        Pop(s1);
        if(!isEmpty(s1))
        {
            getTop(s1,t);
            Pop(s1);
            Push(s1,t->lchild);
            if(t->lchild)
                Push(s2,t->lchild);
            t=t->lchild;
        }
    }
    while(!isEmpty(s2))
    {
        getTop(s2,t);
        printf("%c",t->data);
        Pop(s2);
    }
}

//初始化栈
void InitStack(Stack &s)
{
    s.top=0;
}

//判断栈是否满了,若是,则返回1,否则返回0.
int isFull(Stack s)
{
    if(s.top>=MAX)
        return 1;
    else
        return 0;
}

//判断栈是否为空,若是,返回1,否则返回0
int isEmpty(Stack s)
{
    if(s.top==0)
        return 1;
    else
        return 0;
}

//入栈,若成功,则返回1,否则返回0
int Push(Stack &s,BiTree t)
{
    if(isFull(s))
        return 0;
    else
    {
        s.data[s.top]=t;
        s.top++;
        return 1;
    }
}

//出栈,若出栈成功,则返回1,否则返回0
int Pop(Stack &s)
{
    if(isEmpty(s))
        return 0;
    else
    {
        s.top--;
        return 1;
    }
}

//获得栈顶元素,成功返回1,失败返回0
int getTop(Stack &s,BiTree &t)
{
    if(isEmpty(s))
        return 0;
    else
    {
        t=s.data[s.top-1];
        return 1;
    }
}



这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。

剑指Offer面试题6(Java版):重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重新构造出该二叉树。假设输入的前序遍历和中序遍历的结果中不包含重复的数字。例如输入的前序遍历序列为{1,2,4,7,3,5,6,8}和中序遍历为{4,7...
  • jsqfengbao
  • jsqfengbao
  • 2015年07月27日 18:36
  • 4867

数据结构:关于重建二叉树的三种思路

如果,告诉你有一棵二叉树前序遍历的结果为:ABC;中序遍历的结果为:BAC。我们可以很轻松地写出这棵二叉树就是以A为根节点、其左孩子是B、右孩子是C。那么从代码的角度,或者说是从算法的角度又要怎么来编...
  • u013761665
  • u013761665
  • 2015年11月24日 00:27
  • 4693

POJ 2255 二叉树的重建

很不错的一道题目,t
  • he012
  • he012
  • 2014年07月21日 10:48
  • 225

剑指offer--重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5...
  • kangaroo835127729
  • kangaroo835127729
  • 2015年04月10日 22:57
  • 1974

编程之美--重建二叉树

给定一个前序和中序变量的结果,写一个算法重建这棵树:如: 前序: a b d c e f 中序:  d b a e c f 前序遍历的每一个节点,都是当前子树的根节点,同时,以对应的...
  • luyafei_89430
  • luyafei_89430
  • 2013年10月23日 10:02
  • 6938

openjudge 重建二叉树3

建立二叉树3 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65535kB 描述 给出一颗二叉树每层节点的字符串表示,建立这颗二叉树,并输出中序遍历的结果。   输入 第一行输入一个...
  • kucece
  • kucece
  • 2015年06月05日 20:21
  • 411

java实现重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,...
  • Bryan__
  • Bryan__
  • 2016年09月02日 12:10
  • 1372

重建二叉树 C语言实现

主要根据编程之美中利用前序与中序遍历实现二叉树的重构。其中对于前序遍历中的每一个节点都是当前子树的根节点这一理论来对中序遍历进行划分。 并且也实现了根据中序遍历与后序遍历实现二叉树的重构,其中对于后...
  • yyme411
  • yyme411
  • 2013年11月08日 20:01
  • 1108

Java笔记---剑指Offer(一:Java实现重建二叉树)

一、前言 最近正在准备找实习,因此拿起《剑指Offer》来看看,突击下自己的基础。但是《剑指Offer》上面的算法都是使用C语言,个人对C语言不熟悉,因此使用自己熟悉的Java来实现。嗯,以后要是机试...
  • GuLu_GuLu_jp
  • GuLu_GuLu_jp
  • 2016年03月09日 11:15
  • 958

根据前序和中序重建二叉树

注意:1、仅根据前序和后序无法构建唯一的二叉树;2、二叉树前序遍历,第一个数字总是树的根节点的值;3、中序遍历中,根节点的值在序列的中间,左子树的值子在根节点的值得左边,右字树的值在根节点的值得右边;...
  • dutsoft
  • dutsoft
  • 2014年05月21日 15:13
  • 942
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:二叉树重建(一)
举报原因:
原因补充:

(最多只允许输入30个字)