【问题标题】:How should I define a function that return reference to a pointer? (reference to pointer vs pointer to pointer)我应该如何定义一个返回对指针的引用的函数? (对指针的引用与指向指针的指针)
【发布时间】:2019-07-03 09:42:21
【问题描述】:

我想实现以下功能:在二叉搜索树中删除某个值的节点。我想通过两个步骤来做到这一点: 1.找到值的节点 2.删除节点。

//Definition for a binary tree node.
struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

为了简化问题,假设要删除的节点是叶子,那么我们可以直接删除。

我已经实现了返回对treenode指针的引用的搜索功能,所以我可以直接改变树结构而不需要跟踪父节点。但它不起作用(节点没有被删除)。

TreeNode *&searchBST(TreeNode *&root, int val)
{
    if (!root)
        return root;
    if (root->val == val)
        return root;
    else if (root->val > val)
    {
        return searchBST(root->left, val);
    }
    else
    {
        return searchBST(root->right, val);
    }
}

我还实现了搜索函数,它返回指向树节点指针的指针,它可以工作。

TreeNode **searchBST(TreeNode *&root, int val)
{
    if (!root)
        return &root;
    if (root->val == val)
        return &root;
    else if (root->val > val)
    {
        return searchBST(root->left, val);
    }
    else
    {
        return searchBST(root->right, val);
    }
}

完整代码:

#include <iostream>
using namespace std;

//Definition for a binary tree node.
struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
TreeNode *&searchBST(TreeNode *&root, int val)
{
    if (!root)
        return root;
    if (root->val == val)
        return root;
    else if (root->val > val)
    {
        return searchBST(root->left, val);
    }
    else
    {
        return searchBST(root->right, val);
    }
}
TreeNode *deleteNode(TreeNode *root, int key)
{
    TreeNode *node = searchBST(root, key);
    if (!node)
        return root;
    node = NULL;
    return root;

}
int main()
{
    TreeNode n1(1), n2(0), n3(2);
    n1.left = &n2;
    n1.right = &n3;
    TreeNode *res = deleteNode(&n1, 2);
    return 0;
}

有效的代码:

#include <iostream>
using namespace std;

//Definition for a binary tree node.
struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
TreeNode **searchBST(TreeNode *&root, int val)
{
    if (!root)
        return &root;
    if (root->val == val)
        return &root;
    else if (root->val > val)
    {
        return searchBST(root->left, val);
    }
    else
    {
        return searchBST(root->right, val);
    }
}
TreeNode *deleteNode(TreeNode *root, int key)
{
    TreeNode **node = searchBST(root, key);
    if (!node)
        return root;
    *node = NULL;
    return root;
}
int main()
{
    TreeNode n1(1), n2(0), n3(2);
    n1.left = &n2;
    n1.right = &n3;
    TreeNode *res = deleteNode(&n1, 2);
    if (res->right != NULL)
        cout << res->right->val << endl;
    return 0;
}

【问题讨论】:

  • “它不起作用”是什么意思?如果有编译器错误,您应该将它们包含在问题中
  • 这里似乎没问题:wandbox.org/permlink/Y9TTkNGig1rQ0GLe
  • 很抱歉给您带来了困惑。可以编译但节点没有被删除。
  • 你怎么知道的?没有输出...
  • 再次强调:deleteNode 与众不同。 *node = NULL;node = NULL; 非常不同

标签: c++


【解决方案1】:

我应该如何定义一个返回指针引用的函数?

你写TreeNode *&amp;searchBST(TreeNode *&amp;root, int val) 的方式很好。您问题的前提是错误的:您的工作版本和非工作版本之间的区别不是searchBST,而是deleteNode

这里:

TreeNode *deleteNode(TreeNode *root, int key)
{
    TreeNode *node = searchBST(root, key);
    if (!node)
        return root;
    node = NULL;
    return root;

}

node 是一个局部变量,将NULL 分配给它对实际的树没有任何影响。

另一方面:

TreeNode *deleteNode(TreeNode *root, int key)
{
    TreeNode **node = searchBST(root, key);
    if (!node)
        return root;
    *node = NULL;
    return root;
}

node 是指向您存储在树中的实际指针的指针。因此,您可以取消引用它以分配给树中的指针。

如何释放我删除的节点空间?

你没有!

删除*节点不起作用。

为什么要使用 delete ?您从未使用过new,因此您也不应该使用delete 来释放内存。主要:

int main()
{
    TreeNode n1(1), n2(0), n3(2);
    //...
}   // <---

【讨论】:

  • "节点是一个局部变量,给它分配 NULL 对实际的树没有任何影响。"这是否意味着 node 是一个局部变量,所以它不能被设置为非局部变量的引用?
  • @RickLi 也许TreeNode *&amp; node = searchBST(root, key); 会起作用,但我不愿意提供进一步的建议,因为我不习惯手写树实现,我可能会使用一些标准容器,因为我确信我自己的实现会大错特错
  • @RickLi 换句话说:是的,你可以在本地声明一个引用树中节点的引用,但是在你的代码中你复制了node
  • 非常感谢,我现在明白了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-10
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 2015-02-13
  • 1970-01-01
相关资源
最近更新 更多