二叉排序树的判定(北林OJ288)
描述
假设二叉树每个结点的元素均为一个单字符,根据给定的字符序列按照先序遍历的顺序递归创建该树的二叉链表,然后判断该二叉树是否为二叉排序树。
输入
多组数据,每组数据有一行。每行为一个二叉树对应的前序序列(其中‘#’表示空树)。当序列为“#”时,输入结束。
输出
每组数据输出1行,若此二叉树为二叉排序树则输出“YES”,否则输出“NO”。
输入样例 1
ba##c##
ca##b##
#
输出样例 1
YES
NO
根据定义判断
二叉树的定义:
二叉排序树或者是一棵空树或者是具有下列性质的二叉树
- 若它的左子树不空则左子树上所有节点的值均小于它根节点的值
- 若它的右子树不空则右子树上所有节点的值均大于它根节点的值
- 它的左右子树也分别为二叉排序树
#include<iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define MaxSize 100
typedef char ElemType;
struct BiTree
{
ElemType data;
BiTree* leftchild;
BiTree* rightchild;
};
//创建二叉树
void Create_Tree(BiTree*& T)
{
ElemType ch;
cin >> ch;
if (ch == '#')
T = NULL;
else
{
//创建根节点
T = new BiTree;
T->data = ch;
Create_Tree(T->leftchild);
Create_Tree(T->rightchild);
}
}
//销毁二叉树
void Destory(BiTree*& T)
{
if (T != NULL)
{
Destory((*T).leftchild);
Destory((*T).rightchild);
delete T;//最后删除头节点
T = NULL;
}
}
//判断是否为二叉排序树
bool Is_BSTree(BiTree*& T)
{
if (T == NULL)
return true;
if ((*T).leftchild!=NULL&&(*T).leftchild->data >(*T).data)//error
{
return false;
}
if ((*T).rightchild!=NULL&&(*T).rightchild->data <(*T).data)//error
{
return false;
}
bool left = Is_BSTree((*T).leftchild);//判断左树是否为
bool right = Is_BSTree((*T).rightchild);//判断右树是否为
return left && right;
}
void test288()
{
while (1)
{
BiTree* T;
Create_Tree(T);
if (!T)
break;
bool flag = Is_BSTree(T);
if (flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
Destory(T);
}
}
int main()
{
test288();
return 0;
}
根据性质判断:
二叉树的中序遍历是递增的有序序列
这里借用了顺序表来存储其中序序列
#include<iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define MaxSize 100
typedef char ElemType;
struct BiTree
{
ElemType data;
BiTree* leftchild;
BiTree* rightchild;
};
struct Sqlist
{
ElemType* arr;
int size;
int capacity;
};
//顺序表的初始化
void Init_sq(Sqlist* Q)
{
Q->arr =(ElemType*) malloc(sizeof( ElemType)*10);
Q->size = 0;
Q->capacity = 10;
}
//判断顺序表是否已满
bool IsFull_sq(const Sqlist* Q)
{
if (Q->capacity == Q->size)
return true;
return false;
}
//插入
void pushB_sq(Sqlist* Q, ElemType e)
{
if (IsFull_sq(Q))
{
//扩容
realloc(Q, static_cast<size_t>(Q->size) * 2);
}
Q->arr[Q->size] = e;
Q->size++;
}
//创建二叉树
void Create_Tree(BiTree*& T)
{
ElemType ch;
cin >> ch;
if (ch == '#')
T = NULL;
else
{
//创建根节点
T = new BiTree;
T->data = ch;
Create_Tree(T->leftchild);
Create_Tree(T->rightchild);
}
}
//销毁二叉树
void Destory(BiTree*& T)
{
if (T != NULL)
{
Destory((*T).leftchild);
Destory((*T).rightchild);
delete T;//最后删除头节点
T = NULL;
}
}
//二叉树的中序遍历
void Index_T(BiTree*& T, Sqlist *Q)
{
if (!T)
return;
//遍历左子树
Index_T(T->leftchild, Q);
//将根节点的值存入数组
//判断空间是否足够,不够就扩容
pushB_sq(Q,T->data);
//遍历右子树
Index_T(T->rightchild, Q);
}
//中序判断否为二叉排序树 :二叉排序树的中序遍历是升序
bool Is_BSTree2(BiTree*& T)
{
Sqlist* Q = new Sqlist;
Init_sq(Q);
//将其中序遍历结果存储并判断是否为升序
Index_T(T, Q);
//判断
int i = 0;
for (; i < (Q->size - 1) && Q->arr[i] < Q->arr[i+1]; i++)
;
if (i >= 0 && i < Q->size - 1)
return false;
else
return true;
}
void test288()
{
while (1)
{
BiTree* T;
Create_Tree(T);
if (!T)
break;
bool flag = Is_BSTree2(T);
if (flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
Destory(T);
}
}
int main()
{
test288();
return 0;
}