第7题 判定给定的二叉树是否为二叉排序树
编写算法,判定给定的二叉树是否是一棵二叉排序树。
得分点(必背)
代码语言:javascript复制//数据结构定义
typedef struct node {
int data; // 节点存储的数据
struct node *lchild, *rchild; // 左右子树指针
} Bitree;
//判断二叉树是否为二叉排序树
int IsSearchTree(const Bitree *s) {
if (s == NULL) { // 空二叉树情况
return 1;
} else if (s->lchild == NULL && s->rchild == NULL) { // 左右子树都无情况
return 1;
} else if (s->lchild && s->rchild == NULL) { // 只有左子树情况
if (s->lchild->data > s->data) { // 左子树的值不应大于根节点的值
return 0;
} else {
return IsSearchTree(s->lchild);
}
} else if (s->lchild == NULL && s->rchild) { // 只有右子树情况
if (s->rchild->data < s->data) { // 右子树的值不应小于根节点的值
return 0;
} else {
return IsSearchTree(s->rchild);
}
} else { // 左右子树都有情况
if (s->lchild->data > s->data || s->rchild->data < s->data) { // 检查左右子树的值是否满足BST性质
return 0;
} else {
return IsSearchTree(s->lchild) && IsSearchTree(s->rchild);
}
}
}
题解:判定给定的二叉树是否为二叉排序树
数据结构定义
代码语言:javascript复制typedef struct node {
int data; // 节点存储的数据
struct node *lchild, *rchild; // 左右子树指针
} Bitree;
data
:存储节点的数据。lchild
:指向左子树的指针。rchild
:指向右子树的指针。
判断二叉树是否为二叉排序树
代码语言:javascript复制int IsSearchTree(const Bitree *s) {
if (s == NULL) { // 空二叉树情况
return 1;
} else if (s->lchild == NULL && s->rchild == NULL) { // 左右子树都无情况
return 1;
} else if (s->lchild && s->rchild == NULL) { // 只有左子树情况
if (s->lchild->data > s->data) { // 左子树的值不应大于根节点的值
return 0;
} else {
return IsSearchTree(s->lchild);
}
} else if (s->lchild == NULL && s->rchild) { // 只有右子树情况
if (s->rchild->data < s->data) { // 右子树的值不应小于根节点的值
return 0;
} else {
return IsSearchTree(s->rchild);
}
} else { // 左右子树都有情况
if (s->lchild->data > s->data || s->rchild->data < s->data) { // 检查左右子树的值是否满足BST性质
return 0;
} else {
return IsSearchTree(s->lchild) && IsSearchTree(s->rchild);
}
}
}
详细解释
1. 空二叉树情况
代码语言:javascript复制if (s == NULL) {
return 1;
}
- 如果树是空的(根节点为NULL),则它是二叉排序树,返回1(true)。
2. 左右子树都无情况
代码语言:javascript复制else if (s->lchild == NULL && s->rchild == NULL) {
return 1;
}
- 如果节点
s
没有左右子树,则它是叶子节点,满足BST的性质,返回1(true)。
3. 只有左子树情况
代码语言:javascript复制else if (s->lchild && s->rchild == NULL) {
if (s->lchild->data > s->data) {
return 0;
} else {
return IsSearchTree(s->lchild);
}
}
- 如果节点
s
只有左子树:- 检查左子树的根节点的值是否大于当前节点的值。如果是,返回0(false)。
- 否则,递归检查左子树是否为二叉排序树。
4. 只有右子树情况
代码语言:javascript复制else if (s->lchild == NULL && s->rchild) {
if (s->rchild->data < s->data) {
return 0;
} else {
return IsSearchTree(s->rchild);
}
}
- 如果节点
s
只有右子树:- 检查右子树的根节点的值是否小于当前节点的值。如果是,返回0(false)。
- 否则,递归检查右子树是否为二叉排序树。
5. 左右子树都有情况
代码语言:javascript复制else {
if (s->lchild->data > s->data || s->rchild->data < s->data) {
return 0;
} else {
return IsSearchTree(s->lchild) && IsSearchTree(s->rchild);
}
}
- 如果节点
s
既有左子树又有右子树:- 检查左子树的根节点的值是否大于当前节点的值,或者右子树的根节点的值是否小于当前节点的值。如果是,返回0(false)。
- 否则,递归检查左子树和右子树是否都为二叉排序树,返回它们的逻辑与(即两者都为真时返回1)。
测试代码
为了验证我们的函数,我们需要构建一些二叉树,并调用IsSearchTree
函数进行测试。以下是测试代码:
#include <iostream>
using namespace std;
typedef struct node {
int data;
struct node *lchild, *rchild;
} Bitree;
// 判断二叉树是否为二叉排序树的函数
int IsSearchTree(const Bitree *s) {
if (s == NULL) { // 空二叉树情况
return 1;
} else if (s->lchild == NULL && s->rchild == NULL) { // 左右子树都无情况
return 1;
} else if (s->lchild && s->rchild == NULL) { // 只有左子树情况
if (s->lchild->data > s->data) { // 左子树的值不应大于根节点的值
return 0;
} else {
return IsSearchTree(s->lchild);
}
} else if (s->lchild == NULL && s->rchild) { // 只有右子树情况
if (s->rchild->data < s->data) { // 右子树的值不应小于根节点的值
return 0;
} else {
return IsSearchTree(s->rchild);
}
} else { // 左右子树都有情况
if (s->lchild->data > s->data || s->rchild->data < s->data) { // 检查左右子树的值是否满足BST性质
return 0;
} else {
return IsSearchTree(s->lchild) && IsSearchTree(s->rchild);
}
}
}
// 创建新节点的辅助函数
Bitree* createNode(int data) {
Bitree* newNode = new Bitree();
newNode->data = data;
newNode->lchild = newNode->rchild = NULL;
return newNode;
}
int main() {
// 创建一个二叉排序树
Bitree* root = createNode(10);
root->lchild = createNode(5);
root->rchild = createNode(15);
root->lchild->lchild = createNode(3);
root->lchild->rchild = createNode(7);
root->rchild->rchild = createNode(20);
// 测试是否为二叉排序树
if (IsSearchTree(root)) {
cout << "该二叉树是二叉排序树" << endl;
} else {
cout << "该二叉树不是二叉排序树" << endl;
}
// 创建一个非二叉排序树
Bitree* root2 = createNode(10);
root2->lchild = createNode(5);
root2->rchild = createNode(15);
root2->lchild->lchild = createNode(3);
root2->lchild->rchild = createNode(12); // 12 大于 10,不满足二叉排序树性质
// 测试是否为二叉排序树
if (IsSearchTree(root2)) {
cout << "该二叉树是二叉排序树" << endl;
} else {
cout << "该二叉树不是二叉排序树" << endl;
}
return 0;
}
运行结果
代码语言:javascript复制该二叉树是二叉排序树
该二叉树不是二叉排序树