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

C语言中BST奇偶/负数统计函数countIf异常问题排查

问题:二叉搜索树统计函数countIf在含负数的数据集上失效的原因分析

你的countIf函数递归遍历的逻辑本身是没问题的,但问题出在**isOdd函数对负数奇数的判断逻辑**上——这是C语言取模运算的特性导致的容易踩的小坑!

问题根源

先看你的isOdd实现:

int isOdd (TreeItem n) { return n%2; }

在C语言中,取模运算的结果符号和被除数保持一致:

  • 正数奇数:比如5%2返回1,此时isOdd返回1,符合预期(代表是奇数)
  • 负数奇数:比如-5%2返回**-1**,而不是你预期的1!

当countIf累加这个返回值时,-1会被计入总和,相当于抵消了一个有效计数。比如你的第二个测试集里有-5和-9两个负数奇数,它们会贡献-2而不是+2,直接导致最终统计结果比实际值少了4,自然就出错了。

反观你的isEven函数:

int isEven (TreeItem n) { return !(n%2); }

它之所以没问题,是因为不管n%2返回0、1还是-1,取反后都会得到正确的0或1:

  • 偶数(包括负偶数):n%2是0,!0为1,正确
  • 奇数(包括负奇数):n%2是1或-1,!1和!(-1)都是0,正确

修复方案

把isOdd改成明确返回0或1的逻辑,避免依赖取模结果的符号:

方案1:直接判断取模结果是否非零

int isOdd (TreeItem n) { return (n % 2 != 0); }

不管n%2返回1还是-1,只要不等于0,就说明是奇数,返回1,否则返回0。

方案2:用位运算更高效(推荐)

奇数的二进制最后一位永远是1(补码表示下,正负奇数都适用),所以可以直接判断最低位:

int isOdd (TreeItem n) { return ((n & 1) != 0); }

位运算不仅效率更高,还能彻底避免取模运算的符号问题,逻辑更可靠。

额外验证

你的isNegative函数逻辑是正确的:

int isNegative (TreeItem n) { return (n < 0); }

负数返回1,非负数返回0,累加后能正确统计负数节点数量,不会出现类似问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:54:08