关闭

二叉树重建(一)

111人阅读 评论(0) 收藏 举报
分类:

问题描述

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

主要算法

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

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

代码

/*
功能:二叉树重建(根据先序遍历和中序遍历获取二叉树的后序遍历)
作者: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;
    }
}



这里写图片描述

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:23300次
    • 积分:863
    • 等级:
    • 排名:千里之外
    • 原创:65篇
    • 转载:13篇
    • 译文:0篇
    • 评论:2条
    最新评论