数据结构与算法题目集(中文)7-28 搜索树判断 (25 分)(C语言)
对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。如果我们交换每个节点的左子树和右子树,得到的树叫做镜像二叉搜索树。
现在我们给出一个整数键值序列,请编写程序判断该序列是否为某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,如果是,则输出对应二叉树的后序遍历序列。
输入格式:
输入的第一行包含一个正整数N(≤1000),第二行包含N个整数,为给出的整数键值序列,数字间以空格分隔。
输出格式:
输出的第一行首先给出判断结果,如果输入的序列是某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,则输出YES,否侧输出NO。如果判断结果是YES,下一行输出对应二叉树的后序遍历序列。数字间以空格分隔,但行尾不能有多余的空格。
思路
镜像二叉搜索树的先序遍历,等价于原树按照 根-右-左的顺序遍历。先建立 二叉搜索树,按照二叉树先序和镜像树的先序遍历两次,分别存入数组, 对比原序列。
如果是镜像树,输出的后序遍历顺序是 右-左-根。
代码:
#include<stdio.h>
#include<stdlib.h>
#define MAX 1001
typedef struct TNode *BinTree;
typedef struct TNode{
int data;
BinTree lchild, rchild;
}BTree;
BinTree Create(BinTree BT, int value);//建二叉排序树
void PreOrd(BinTree BT, int pre[]);//先序遍历 存入数组pre
void Mir_PreOrd(BinTree BT, int mir[]);//镜像树 先序遍历 存入数组mir
void PosOrdPrint(BinTree BT, int n);//后序打印
void Mir_PosOrdPrint(BinTree BT, int n);//镜像树 后序打印
int Flag(int a[], int b[], int n); //和输入比较
int main()
{
int n, i, sam[MAX], pre[MAX], mir[MAX];
BinTree root=NULL;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&sam[i]);
root = Create(root, sam[i]);
}
PreOrd(root, pre);
Mir_PreOrd(root,mir);
if(Flag(sam, pre, n)){
printf("YES\n");
PosOrdPrint(root, n);
}else if(Flag(sam,mir,n))
{
printf("YES\n");
Mir_PosOrdPrint(root, n);
}else printf("NO\n");
return 0;
}
BinTree Create(BinTree BT, int value)
{
if(!BT)
{
BT = (BinTree) malloc(sizeof(BTree));
BT->data = value;
BT->lchild = BT->rchild = NULL;
}else{
if(BT->data > value ) BT->lchild = Create(BT->lchild, value);
else if(BT->data <= value) BT->rchild = Create(BT->rchild, value);
}
return BT;
}
void PreOrd(BinTree BT, int pre[])
{
static int i = 0;
if(BT)
{
pre[i++] = BT->data;
PreOrd(BT->lchild, pre);
PreOrd(BT->rchild, pre);
}else return;
}
void Mir_PreOrd(BinTree BT, int mir[])
{
static int i =0;
if(BT)
{
mir[i++] = BT->data;
Mir_PreOrd(BT->rchild, mir);
Mir_PreOrd(BT->lchild, mir);
}else return;
}
void PosOrdPrint(BinTree BT, int n)
{
static int i = 0;
if(BT)
{
PosOrdPrint(BT->lchild, n);
PosOrdPrint(BT->rchild, n);
printf("%d",BT->data);
if(++i < n) printf(" ");
}else return;
}
void Mir_PosOrdPrint(BinTree BT, int n)
{
static int i = 0;
if(BT)
{
Mir_PosOrdPrint(BT->rchild, n);
Mir_PosOrdPrint(BT->lchild, n);
printf("%d",BT->data);
if(++i < n) printf(" ");
}else return;
}
int Flag(int a[], int b[], int n)
{
int i;
for(i=0;i<n;i++)
{
if(a[i]!= b[i]) return 0;
}
return 1;
}