我想实现以下功能:删除二叉搜索树中某个值的节点。我想通过两个步骤来做到这一点: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 *&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的指针的指针,并且可以正常工作。
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;
}
答案 0 :(得分:1)
我应该如何定义一个返回对指针的引用的函数?
您写TreeNode *&searchBST(TreeNode *&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);
//...
} // <---
n1
,n2
和n3
使用自动存储,当它们超出范围时(即main
返回<---
时)会受到破坏。