判断二叉排序树
一、小组信息
学号 | 姓名 |
---|---|
二、题目以及功能实现:
题目8:判断一棵树是否为一棵二叉排序树。
实验内容如下:
(1)构建一棵二叉树
(2)输出二叉树的先序、中序、后序遍历序列
(3)判断是否为一棵二叉排序树
三、题目分析:
- 构建一棵二叉树
二叉树主要有顺序存储结构和链式存储结构两种存储方式,因顺序存储主要应用于完全二叉树和满二叉树,否则容易造成大量存储空间的浪费。因此,本题中适用于一般的二叉树,采用二叉链表构建二叉树。 - 输出二叉树的的先序、中序、后序遍历序列
利用二叉树的递归定义,二叉树的遍历只需依次遍历二叉树的根节点、左子树和右子树三个基本部分。根据访问顺序的不同可以得到DLR(先序遍历),LDR(中序遍历),LRD(后序遍历)。 - 判断一棵树是否为一棵二叉排序树
根据二叉排序树(BST)的定义知,二叉排序树或为空二叉树,或为具有以下性质的二叉树:
(1) 左子树上的所有结点的关键字均小于根节点的关键字;
(2) 右子树上的所有结点的关键字均大于根节点的关键字;
(3) 左子树和右子树又各是一棵二叉排序树。
因此,我们有几种思路,由(1)知,对二叉树进行递归遍历,左子树关键字比根结点关键字小,右子树的关键字比根结点的关键字大,一旦有不满足条件则可判断不是二叉排序树;由(1)(2)知,左子树结点值<根结点值<右子树结点值,其中序遍历序列是一个递增序列,因此,对给定的二叉树进行中序遍历,如果始终能保持前一个值比后一个值小,则说明该二叉树是一棵二叉排序树,反之则不然。
四、数据结构定义:
五、关键部分程序实现(主要函数):
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define maxsize 1024
int predt = -32756;
typedef int datatype;
//二叉链表结点定义
typedef struct node{
datatype data;
struct node *lchild,*rchild;
}bitree;
//二叉树的建立
bitree *CreatTree(){
int num;
bitree *Q[maxsize];//设置指针类型构成队列
int front,rear;
bitree *root,*s;
root = NULL;//二叉树置空
front = 1;
rear = 0;
scanf("%d",&num);
while(num!=-1){
s = NULL;
if(num!=0){
s = (bitree*)malloc(sizeof(bitree));
s->data = num;
s->lchild = NULL;
s->rchild = NULL;
}
rear++;
Q[rear] = s;
if(rear == 1){
root = s;
}else {
if(s&&Q[front]){
if(rear%2==0){
Q[front]->lchild = s;
}else {
Q[front]->rchild = s;
}
if(rear%2 == 1){
front++;
}
}
}
scanf("%d",&num);
}
return root;
}
//DLR
void preorder(bitree*p){
if(p!=NULL){
printf("%d ",p->data);
preorder(p->lchild);
preorder(p->rchild);
}
}
//LDR
void inorder(bitree*p){
if(p!=NULL){
inorder(p->lchild);
printf("%d ",p->data);
inorder(p->rchild);
}
}
//LRD
void posorder(bitree*p){
if(p!=NULL){
posorder(p->lchild);
posorder(p->rchild);
printf("%d ",p->data);
}
}
//判断是否为二叉排序树
int isBST(bitree*p){
int b1,b2;
if(p == NULL) return 1;//空树
else{
b1 = isBST(p->lchild);
if(b1 == 0||predt > p->data) return 0;
predt = p->data;
b2 = isBST(p->rchild);
return b2;
}
}
//主函数
int main(){
printf("请输入数据:");
bitree *root = CreatTree();
printf("先序:");
preorder(root);
printf("\n");
printf("中序:");
inorder(root);
printf("\n");
printf("后序:");
posorder(root);
printf("\n");
if(isBST(root)){
printf("该树是一棵二叉排序树");
}else printf("该树不是一棵二叉排序树");
}
六、执行结果:
练习例程一:
练习例程二:
七、个人总结:
姓名:
通过本次大作业一练习,成功实现了题目的要求,但仍有很多不足之处。在二叉排序树的数据存储中并没有使用字符类型,为了方便起见使用了整型,用数字0代替原本的零输入’@’,数字-1代替原本的结束符号“#”。因此,忽略了属于数据有0和-1的情形。在大作业交了之后,会花些时间继续改善代码使其更具有普适性。