You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的BST验证函数返回false?代码问题排查求助

BST插入与验证问题排查

问题描述

我实现了二叉搜索树(BST)的push插入函数和验证BST有效性的check函数。我认为自己构建的输入是合法BST,但check函数返回false,无法找到原因。

我设计的check函数做了四项检查:

  • 左子节点数据小于当前节点
  • 右子节点数据大于当前节点
  • 递归检查左子树
  • 递归检查右子树

按逻辑应该返回true,但实际返回false,需要排查问题。

原始代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct tree{
    int data;
    struct tree* left;
    struct tree* right;
};

struct tree* push(int d,struct tree*head1) {
    if(head1==NULL){
        head1=(struct tree*) malloc(sizeof(struct tree));
        head1->data=d;
        head1->left=head1->right=NULL;
        return head1;
    }
    else if(head1->data>d){
        head1->right=push(d,head1->right);
    }
    else{
        head1->left=push(d,head1->left);
    }
    return head1;
}

bool small(struct tree* a,int b){
    if(a==NULL){return true;}
    if(a->data<b){return true;}
    else {return false;}
}

bool large(struct tree* a,int b){
    if(a==NULL){return true;}
    if(a->data>b ){return true;}
    else {return false;}
}

bool check(struct tree*head ){
    if(head==NULL){
        printf("empty\n");
        return true;
    }
    printf("2");
    if(small(head->left,head->data)&& large(head->right,head->data) && check(head->left) && check(head->right)){
        printf("true");
        return true;
    }
    else {
        printf("false\n");
        return false;
    }
}

int main(){
    struct tree*head;
    head=push(3,head);
    head=push(10,head);
    head=push(5,head);
    check(head);
    // printf("%d",head->data);
    return 0;
}

错误排查与修正

1. push函数插入逻辑完全颠倒

BST的核心规则是左子树所有节点值小于当前节点,右子树所有节点值大于当前节点,但你的push函数逻辑写反了:

  • 当当前节点值大于插入值时,应该插入左子树,你却插入到了右子树
  • 当当前节点值小于等于插入值时,应该插入右子树,你却插入到了左子树

这直接导致构建的树根本不是BST:

  • 插入3 → 根节点为3
  • 插入10:3<10,按错误逻辑插入到左子树
  • 插入5:根节点3<5,插入到左子树;左子树节点10>5,插入到10的右子树
    最终树结构完全不符合BST规则,check函数自然返回false。

修正后的push函数:

struct tree* push(int d, struct tree* head1) {
    if (head1 == NULL) {
        head1 = (struct tree*)malloc(sizeof(struct tree));
        head1->data = d;
        head1->left = head1->right = NULL;
        return head1;
    }
    // 小于当前节点,插入左子树
    else if (head1->data > d) {
        head1->left = push(d, head1->left);
    }
    // 大于等于当前节点,插入右子树
    else {
        head1->right = push(d, head1->right);
    }
    return head1;
}

2. check函数验证逻辑不完整

你的check函数只检查了直接子节点与当前节点的大小关系,但BST要求左子树所有节点都小于当前节点,右子树所有节点都大于当前节点,而非仅直接子节点。比如下面的树:

5
   / \
  3   7
   \
    6

直接子节点3<5、7>5,但左子树里的6>5,属于无效BST,但你的check函数会误判为有效。

需要修改check函数,传递当前节点允许的取值范围(下界和上界):

修正后的check函数及辅助逻辑:

#include <limits.h> // 需引入此头文件使用INT_MIN和INT_MAX

bool checkRange(struct tree* head, int minVal, int maxVal) {
    if (head == NULL) return true;
    // 当前节点值必须在[minVal, maxVal]范围内
    if (head->data <= minVal || head->data >= maxVal) return false;
    // 左子树的上界是当前节点值,下界不变
    // 右子树的下界是当前节点值,上界不变
    return checkRange(head->left, minVal, head->data) && checkRange(head->right, head->data, maxVal);
}

bool check(struct tree* head) {
    // 初始范围设为int的极值,确保根节点不受限制
    return checkRange(head, INT_MIN, INT_MAX);
}

3. 主函数初始化问题

主函数中struct tree* head;未初始化,直接传递给push会导致未定义行为,需要初始化为NULL:

int main(){
    struct tree* head = NULL; // 初始化
    head = push(3, head);
    head = push(10, head);
    head = push(5, head);
    if (check(head)) {
        printf("是有效BST\n");
    } else {
        printf("不是有效BST\n");
    }
    return 0;
}

最终修正后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>

struct tree{
    int data;
    struct tree* left;
    struct tree* right;
};

struct tree* push(int d, struct tree* head1) {
    if (head1 == NULL) {
        head1 = (struct tree*)malloc(sizeof(struct tree));
        head1->data = d;
        head1->left = head1->right = NULL;
        return head1;
    }
    else if (head1->data > d) {
        head1->left = push(d, head1->left);
    }
    else {
        head1->right = push(d, head1->right);
    }
    return head1;
}

bool checkRange(struct tree* head, int minVal, int maxVal) {
    if (head == NULL) return true;
    if (head->data <= minVal || head->data >= maxVal) return false;
    return checkRange(head->left, minVal, head->data) && checkRange(head->right, head->data, maxVal);
}

bool check(struct tree* head) {
    return checkRange(head, INT_MIN, INT_MAX);
}

int main(){
    struct tree* head = NULL;
    head = push(3, head);
    head = push(10, head);
    head = push(5, head);
    if (check(head)) {
        printf("是有效BST\n");
    } else {
        printf("不是有效BST\n");
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者vatsal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 20:14:51