C++ 如果指针指向 nullptr,我可以用数字替换它吗?
C++ if a pointer point to nullptr, can I replace it with number?
大家好,我遇到了一些关于 C++ 的问题。其实不是语言特性的问题,要不然就是编码风格的问题了。
好了,进入正题!
我尝试编写 AVL 树并想计算平衡因子,
根据规则,没有节点的子树(只是一棵空树),
它的高度应该被视为-1。是的,一切都很好,
但是当我编写代码时,使用指针读取 Node class 成员,
我无法读取 nullptr BAD ACCESS,所以我添加了很多条件,这让我的代码看起来很糟糕。这是我的代码的一些部分。
struct Node{
int key;
int height;
Node* left;
Node* right;
Node* parent;
Node(void);
Node(int key);
};
while((parent_node->left->height - parent_node->right->height) <= 1
||(parent_node->left->height - parent_node->right->height) >= (-1))
{
parent_node = parent_node->parent;
if(parent_node == nullptr) break;
}
我想要的结果是当parent_node的左子树为空时,
它的高度将被视为-1。而事实是,虽然它是空的,但它的高度不应该存在。
所以在代码中我只列举了四种情况
1. 左子树 == nullptr && 右子树 == nullptr
2. 左子树 != nullptr && 右子树 == nullptr
3. 左子树 != nullptr && 右子树 != nullptr
4. 左子树 == nullptr && 右子树 != nullptr
然后我将高度部分的代码分别替换为值-1。
感觉很痛。并且这种情况在我的编码时间中多次发生,我想找到更好的解决方案。
我的英文不是很好,所以我的描述可能有点误导,如果你能以任何方式帮助我,我将不胜感激。
除非我误解了,否则你可以指向一个哨兵节点而不是 null 作为终止符 link。将 sentinel 的高度设置为 -1 并且不需要对算法的那部分进行不同的处理。
创建一个计算子树高度的函数,包括特殊情况,并使用它代替访问 ->height
数据成员:
int heightOfSubtree(Node* tree) {
if (tree == nullptr) {
return -1;
}
else {
return tree-> height;
}
}
那么您的代码将变为:
while((heightOfSubtree(parent_node->left) - heightOfSubtree(parent_node->right)) <= 1
||((heightOfSubtree(parent_node->left) - heightOfSubtree(parent_node->right)) >= (-1))
{
...
}
或者更好的是,您可以在 Node
结构中定义一个成员函数,例如:
bool Node::isBalanced() {
int unb = heightOfSubtree(left) - heightOfSubtree(right);
return (unb <= 1) || (unb >=-1);
}
并且您的 while
条件变为:
while(parent_node->isBalanced()) {
...
}
p.s.: 我认为您的代码中存在逻辑错误:我不确定您检查的条件是否正确,因为它始终为真(任何数字大于 -1 或小于 1,有些两者都成立)
大家好,我遇到了一些关于 C++ 的问题。其实不是语言特性的问题,要不然就是编码风格的问题了。
好了,进入正题!
我尝试编写 AVL 树并想计算平衡因子,
根据规则,没有节点的子树(只是一棵空树),
它的高度应该被视为-1。是的,一切都很好,
但是当我编写代码时,使用指针读取 Node class 成员,
我无法读取 nullptr BAD ACCESS,所以我添加了很多条件,这让我的代码看起来很糟糕。这是我的代码的一些部分。
struct Node{
int key;
int height;
Node* left;
Node* right;
Node* parent;
Node(void);
Node(int key);
};
while((parent_node->left->height - parent_node->right->height) <= 1
||(parent_node->left->height - parent_node->right->height) >= (-1))
{
parent_node = parent_node->parent;
if(parent_node == nullptr) break;
}
我想要的结果是当parent_node的左子树为空时,
它的高度将被视为-1。而事实是,虽然它是空的,但它的高度不应该存在。
所以在代码中我只列举了四种情况
1. 左子树 == nullptr && 右子树 == nullptr
2. 左子树 != nullptr && 右子树 == nullptr
3. 左子树 != nullptr && 右子树 != nullptr
4. 左子树 == nullptr && 右子树 != nullptr
然后我将高度部分的代码分别替换为值-1。
感觉很痛。并且这种情况在我的编码时间中多次发生,我想找到更好的解决方案。
我的英文不是很好,所以我的描述可能有点误导,如果你能以任何方式帮助我,我将不胜感激。
除非我误解了,否则你可以指向一个哨兵节点而不是 null 作为终止符 link。将 sentinel 的高度设置为 -1 并且不需要对算法的那部分进行不同的处理。
创建一个计算子树高度的函数,包括特殊情况,并使用它代替访问 ->height
数据成员:
int heightOfSubtree(Node* tree) {
if (tree == nullptr) {
return -1;
}
else {
return tree-> height;
}
}
那么您的代码将变为:
while((heightOfSubtree(parent_node->left) - heightOfSubtree(parent_node->right)) <= 1
||((heightOfSubtree(parent_node->left) - heightOfSubtree(parent_node->right)) >= (-1))
{
...
}
或者更好的是,您可以在 Node
结构中定义一个成员函数,例如:
bool Node::isBalanced() {
int unb = heightOfSubtree(left) - heightOfSubtree(right);
return (unb <= 1) || (unb >=-1);
}
并且您的 while
条件变为:
while(parent_node->isBalanced()) {
...
}
p.s.: 我认为您的代码中存在逻辑错误:我不确定您检查的条件是否正确,因为它始终为真(任何数字大于 -1 或小于 1,有些两者都成立)