根据输入的二叉树中序和后序序列来构造该二叉树,输出该二叉树的前序序列
和该二叉树的度为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");
}
}