二叉树重建(一)

原创 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;
    }
}



这里写图片描述

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

相关文章推荐

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

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5...

二叉树的重建java代码

剑指offer——重建二叉树

1. 题目描述  输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{...

二叉树重建 sicily1935

  • 2011-05-17 21:11
  • 15KB
  • 下载

重建二叉树(Java)

题目:输入某二叉树的前序遍历和中序遍历结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历数列{4,7,2,1...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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