二叉树遍历:已知中序和后序,求前序

根据输入的二叉树中序和后序序列来构造该二叉树,输出该二叉树的前序序列
和该二叉树的度为2的结点的个数并能判断该二叉树是否为二叉排序树(若是输出Yes;否则输出No)。

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void exit(int);

#define MAX 1000

typedef struct node
{
    char d;
    struct node *lchild, *rchild;
}Tnode;
//in[]:中序序列,post[]:后序序列,可知post的最后一个结点即是根
//MK(in, 0, strlen(in) - 1, post, 0, strlen(post) - 1, &r);
void MK(char in[], int is, int ie, char post[], int posts, int poste, Tnode **r)
{
    int i;
    if (is>ie || posts>poste)
    {
        *r = NULL;
    }
    else
    {
        *r = (Tnode *)malloc(sizeof(Tnode));
        (*r)->d = post[poste];
        for (i=is; i<=ie; i++)
        {	
		//后序的最后一个字母(post[poste])为树的根节点,然后查看中序序列中这个字母的位置,它之前的为左子树,之后的为右子树,然后分别对这两个子树的前序和中序序列做同样的步骤即可。
            if (in[i] == post[poste])
				
            {
                MK(in, is, i-1, post, posts, posts+i-is-1, &(*r)->lchild);
                MK(in, i+1, ie, post, posts+i-is, poste-1, &(*r)->rchild);
                break;
            }
            if (i > ie)
            {
                printf("输入错误!\n");
                exit(1);
            }
        }
    }
}

void preorder(Tnode *r)
{
    if (r)
    {
        printf("%c", r->d);
        preorder(r->lchild);
        preorder(r->rchild);
    }
}

int one(Tnode *r)
{
    if ((r == NULL) || (!r->lchild) && (!r->rchild))
    {
        return 0;
    }
    if ((r->lchild) && (r->rchild))
    {
        return one(r->lchild) + one(r->rchild);
    }
    else
    {
        return 1 + one(r->lchild) + one(r->rchild);
    }
}

int two(Tnode *r)
{
    if ((r == NULL) || (!r->lchild) && (!r->rchild))
    {
        return 0;
    }
    if ((r->lchild) && (r->rchild))
    {
        return 1 + two(r->lchild) + two(r->rchild);
    }
    else
    {
        return two(r->lchild) + two(r->rchild);
    }
}


int check(Tnode *t)  //递归遍历二叉树是否为二叉排序树
{
	if(!t)        //空二叉树情况
		return 1;
	else if(!(t->lchild) && !(t->rchild))   //左右子树都无情况
		return 1;
	else if((t->lchild) && !(t->rchild))    //只有左子树情况
	{
		if(t->lchild->d>t->d)
			return 0;
		else
			return check(t->lchild);
	}
	else if((t->rchild) && !(t->lchild))   //只有右子树情况
	{
		if(t->rchild->d<t->d)
			return 0;
		else
			return check(t->rchild);
	}
	else         //左右子树全有情况
	{                                
		if((t->lchild->d>t->d) || (t->rchild->d<t->d))
			return 0;
		else
			return ( check(t->lchild) && check(t->rchild) );
	}
}


void main()
{
    Tnode *r = NULL;
    char in[MAX], post[MAX];
    printf("请输入中序序列:");
    gets(in);
    printf("\n请输入后序序列:");
    gets(post);
    MK(in, 0, strlen(in) - 1, post, 0, strlen(post) - 1, &r);
    printf("\n该二叉树的前序遍历序列为:");
    preorder(r);
    printf("\n\n该二叉树的一度结点个数为:%d\n",one(r));
    printf("\n该二叉树的二度结点个数为:%d\n",two(r));
    printf("\n该二叉树是否为二叉排序树(若是输出Yes,否则输出No):\n");
    if (check(r))
    {
        printf("Yes\n");
    }
    else
    {
        printf("No\n");
    }
}


 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值