原始题目

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
TreeNode* root = new TreeNode(1);
root->left = new TreeNode(2);
root->right = new TreeNode(3);
root->left->left = new TreeNode(4);
root->left->right = new TreeNode(5);
int count = 0;
void countDegree1(TreeNode* root) {
    if (root == nullptr) return;
    if ((root->left != nullptr) != (root->right != nullptr)) count++;
    countDegree1(root->left);
    countDegree1(root->right);
}
countDegree1(root);
cout << count;

问:程序运行后输出什么?

答案

输出 0

解析

这段代码的功能是统计二叉树中度为 1(恰好只有 1 个子节点)的结点个数,采用的是对两个布尔值做异或(XOR)的技巧。

关键判断

if ((root->left != nullptr) != (root->right != nullptr)) count++;
  • root->left != nullptr 是布尔值:true 表示有左孩子。
  • root->right != nullptr 是布尔值:true 表示有右孩子。
  • 两个布尔值做 !=,结果仅当“一个有孩子、另一个没有”时才为 true,即结点的度恰好为 1。

还原树结构

        1
       / \
      2   3
     / \
    4   5
二叉树结构(标注每个结点的度) 1 度2 2 度2 3 度0 4 度0 5 度0 蓝 = 2 度结点,灰 = 0 度结点,无 1 度结点 → count = 0 逐结点判断 结点 左/右 XOR 1 有/有 F 2 2 有/有 F 2 3 无/无 F 0 4 无/无 F 0 5 无/无 F 0 count = 0 → 输出 0

易错点总结

  • 度 = 子节点个数:叶子结点度为 0,满结点的度为 2,只有“独苗”结点(仅左或仅右)度为 1。
  • XOR 写法 (a) != (b) 比写 if (a && !b || !a && b) 更简洁,是判断“恰好满足一个”的常用技巧。
  • 递归顺序:先本结点、再左、再右,等价于前序遍历,遍历完整棵树。

思考题

如果把判断改成 if (root->left != nullptr && root->right != nullptr) count++;,count 会变成多少?

点击查看答案 改成统计「度为 2 的结点」。本树中结点 1、结点 2 都有左右孩子,所以 count = 2