1. 问题描述:
设计一个算法,判断给出的二叉树是否是二叉排序树,假设二叉排序树已经存储在二叉链表的存储结构中,树节点的个数为n,节点值为int类型
2. 思路如下:
① 判断一颗二叉树是否是二叉排序树的方法有好几种,其中最简单的方法是对给定的二叉树进行中序遍历,假如二叉树是二叉排序树那么中序遍历的结果一定是递增的,假如不是那么就不是二叉排序树
② 基于上面的想法我们可以使用中序遍历的方法,使用一个全局变量来记录递归遍历的根节点的值,在遍历过程中遇到叶子节点那么可以直接返回1(为二叉排序树),全局变量实际上记录的是上一次递归过程中的根节点的值,往下是对右子树进行递归遍历,所以在递归完根节点的的左子树之后那么判断上一次递归过程中的根节点与当前节点的值,而当前节点的值恰恰是上一次递归过程中右子树的节点的值,所以判断一下假如发现当前的全局变量的值大于了当前节点的值(上一次根节点的右子树)那么肯定不是二叉排序树直接返回0
③ 为了简单测试一下二叉树是否是二叉排序树那么可以简单手动创建一颗二叉树通过改变其中的值来检测算法是否正确,我们再一开始创建出一颗二叉树之后对其进行遍历判断创建的二叉树是否成功这样才可以进行接下来判断是否是二叉排序树
④ 在创建节点的过程中我们对于节点中没有孩子的节点的指针通通赋值为NULL,这样程序才不会出错
⑤ 下面是具体的C++代码:
#include<iostream>
#include<malloc.h>
//创建一颗二叉树
/*
6
3 9
1 4 7 10
2 5
*/
using namespace std;
typedef struct BSTode{
BSTode *left;
BSTode *right;
int data;
}BSTNode;
BSTNode *root;
int predt = -10000;
int judgeBST(BSTode *bt){
int b1, b2;
if(bt == NULL){
return 1;
}
else{
b1 = judgeBST(bt->left);
if(b1 == 0 || predt > bt->data) return 0;
predt = bt->data;
b2 = judgeBST(bt->right);
return b2;
}
}
//先序遍历
void preOrder(BSTNode *p){
if(p != NULL){
cout << p->data << " ";
preOrder(p->left);
preOrder(p->right);
}
}
int main(void){
root = (BSTode*)(malloc(sizeof(BSTode)));
root->data = 6;
BSTode *l = (BSTode*)(malloc(sizeof(BSTode)));
l->data = 3;
BSTode *r = (BSTode*)(malloc(sizeof(BSTode)));
r->data = 9;
BSTode *ll = (BSTode*)(malloc(sizeof(BSTode)));
ll->data = 1;
BSTode *lr = (BSTode*)(malloc(sizeof(BSTode)));
lr->data = 4;
BSTode *rl = (BSTode*)(malloc(sizeof(BSTode)));
rl->data = 7;
BSTode *rr = (BSTode*)(malloc(sizeof(BSTode)));
rr->data = 10;
BSTode *llr = (BSTode*)(malloc(sizeof(BSTode)));
llr->data = 2;
BSTode *lrr = (BSTode*)(malloc(sizeof(BSTode)));
lrr->data = 5;
root->left = l;
root->right = r;
l->left = ll;
l->right = lr;
r->left = rl;
r->right = rr;
ll->right = llr;
ll->left = NULL;
lr->left = NULL;
lr->right = lrr;
rl->left = NULL;
rl->right = NULL;
rr->left = NULL;
rr->right = NULL;
llr->left = NULL;
llr->right = NULL;
lrr->left = NULL;
lrr->right = NULL;
preOrder(root);
cout << endl << judgeBST(root) << endl;
return 0;
}