力扣题目:给你一个 二叉树 的根结点 root
,该二叉树由恰好 3
个结点组成:根结点、左子结点和右子结点。
如果根结点值等于两个子结点值之和,返回 true
,否则返回 false
。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool checkTree(TreeNode* root) {
return root->val==root->left->val+root->right->val;
}
};
这里用的是,在C++中,->
运算符用于访问指针所指向对象的成员。它结合了两个操作:首先是解引用指针,然后是访问对象的成员。
假设我们有一个指向某个对象的指针,比如TreeNode* root
,那么root->val
的意思是:
root
是一个指向TreeNode
类型对象的指针。->
运算符首先会解引用root
指针,得到它所指向的TreeNode
对象。- 然后,它会访问这个对象的
val
成员。
这与使用.
运算符访问对象成员略有不同,因为.
运算符用于直接访问对象的成员,而不是通过指针。例如,如果root
不是一个指针,而是直接是一个TreeNode
对象,那么我们会使用root.val
来访问它的val
成员。
在C++中,->
运算符是必要的,因为它允许我们通过指针来间接访问对象的成员,这是处理动态分配的(堆上的)对象时非常常见的操作。
#include <iostream>
// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
class Solution {
public:
bool checkTree(TreeNode* root) { // 注意这里的参数类型是TreeNode*
if (!root) return true; // 如果节点为空,返回true
if (!root->left && !root->right) return true; // 如果是叶子节点,也返回true
if (root->left && !checkTree(root->left)) return false; // 递归检查左子树
if (root->right && !checkTree(root->right)) return false; // 递归检查右子树
return root->val == (root->left ? root->left->val : 0) + (root->right ? root->right->val : 0); // 检查当前节点的值是否等于左右子节点值之和
}
};
int main() {
// 示例使用
TreeNode* root = new TreeNode(15);
root->left = new TreeNode(5);
root->right = new TreeNode(10);
Solution solution;
bool result = solution.checkTree(root);
std::cout << (result ? "True" : "False") << std::endl;
// 清理分配的内存
delete root->left;
delete root->right;
delete root;
system("pause");
return 0;
}
checkTree
函数现在接受一个指向TreeNode
的指针作为参数,并且递归地检查整棵树。如果树中的任何一个节点不满足条件(即节点的值不等于其左右子节点值之和),函数将返回false
。如果整棵树都满足条件,函数将返回true
。此外,还添加了对nullptr
的处理,以避免运行时错误。最后,main
函数提供了一个示例,展示了如何使用Solution
类和checkTree
函数。
我要是不用->,用.怎么写?这意味着不能直接传递一个指针到checkTree
函数,而是需要传递一个对象或者对象的引用。
#include <iostream>
// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
class Solution {
public:
bool checkTree(TreeNode& root) { // 使用引用来避免复制整个对象
if (root.left == nullptr && root.right == nullptr) return true; // 叶子节点
if (root.left && root.left->val != root.val - root.right->val) return false; // 左子树检查
if (root.right && root.right->val != root.val - root.left->val) return false; // 右子树检查
return true;
}
};
int main() {
// 示例使用
TreeNode root(10);
root.left = new TreeNode(5);
root.right = new TreeNode(15);
Solution solution;
bool result = solution.checkTree(root);
std::cout << (result ? "True" : "False") << std::endl;
// 清理分配的内存
delete root.left;
delete root.right;
system("pause");
return 0;
}
checkTree
函数接受一个对TreeNode
的引用(TreeNode& root
),这样就可以使用.
运算符来访问root
的成员变量和成员函数。例如,root.val
、root.left
和root.right
。
请注意,使用引用而不是指针可以避免不必要的对象复制,并且在这种情况下更安全,因为你不会意外地修改原始对象的地址。然而,这也意味着需要确保传递给checkTree
的对象在函数执行期间是有效的,特别是在涉及到动态分配的内存时。