从二叉搜索树中删除节点
C++ Delete node from binary search tree
我建立了一个二叉搜索树,并插入了一些随机值节点。我试图实现一个函数来删除节点,但由于某种原因它不起作用。当试图删除给定节点时,似乎被删除节点的父节点和被删除节点的子节点不会"连接"。
有谁能看出我做错了什么吗?我试过多次调试程序,看看我的错误在哪里,但我不明白如何将父节点和子节点连接在一起。这是我的程序:
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* left;
Node* right;
};
Node* insertNode(Node* root, int n);
Node* newNode(int d);
Node* deleteNode(Node* root, int d);
Node* findMin(Node* root);
int main()
{
int num;
Node* rootPtr = NULL;
Node* min;
rootPtr = insertNode(rootPtr, 15);
rootPtr = insertNode(rootPtr, 10);
rootPtr = insertNode(rootPtr, 20);
rootPtr = insertNode(rootPtr, 24);
rootPtr = insertNode(rootPtr, 7);
rootPtr = insertNode(rootPtr, 25);
rootPtr = insertNode(rootPtr, 5);
rootPtr = deleteNode(rootPtr, 7);
cout << "nEnter a number to search for: ";
cin >> num;
if(search(rootPtr, num))
cout << "nFound.";
else
cout << "nNot found.";
cout << endl;
return 0;
}
Node* insertNode(Node* root, int n)
{
if(root == NULL)
root = newNode(n);
else if(n <= root->data)
root->left = insertNode(root->left, n);
else if(n > root->data)
root->right = insertNode(root->right, n);
return root;
}
Node* newNode(int d)
{
Node* newNode = new Node();
newNode->data = d;
newNode->left = newNode->right = NULL;
return newNode;
}
bool search(Node* root, int d)
{
if(root == NULL)
return false;
else if(root->data == d)
return true;
else if(d < root->data)
return search(root->left, d);
else if(d > root->data)
return search(root->right, d);
}
Node* deleteNode(Node* root, int d)
{
if(root == NULL)
return root;
else if(d < root->data)
deleteNode(root->left, d);
else if(d > root->data)
deleteNode(root->right, d);
else
{
if(root->left == NULL && root->right == NULL)
{
delete root;
root = NULL;
}
else if(root->left == NULL)
{
Node* temp = root;
root = root->right;
delete temp;
}
else if(root->right == NULL)
{
Node* temp = root;
root = root->left;
delete temp;
}
else
{
Node* temp = findMin(root->right);
root->data = temp->data;
root->right = deleteNode(root->right, temp->data);
}
}
return root;
}
Node* findMin(Node* root)
{
if(root == NULL)
cout << "nThe tree is empty.";
else
{
Node* temp = root;
while(temp->left != NULL)
temp = temp->left;
return temp;
}
}
在deleteNode()
函数中,节点在递归的返回路径上没有得到连接。您可能需要使用函数的返回值,就像对insertNode()
所做的那样。例如,
else if(d < root->data)
deleteNode(root->left, d);
else if(d > root->data)
deleteNode(root->right, d);
可能是(类似于)
else if(d < root->data)
root->left = deleteNode(root->left, d);
else if(d > root->data)
root->right = deleteNode(root->right, d);
同样,findMin()
的调用者可能同时需要最小节点和它的父节点。让它两个都返回。在deleteNode()
中,您可能需要将父指针的子指针之一设置为NULL。
删除节点时,还需要将存储在父节点中的指针设置为NULL。
假设你有节点p和C,其中p左=C, C是一个叶节点。您的代码将为C释放内存,并将一个临时变量(在您的程序中称为root)设置为NULL。(顺便说一句,使用nullptr而不是NULL。)但是如果检查P的内容,它仍然指的是c的已分配地址。
#include <iostream>
using namespace std;
template<typename T>
class BinaryTree
{
private:
struct Node
{
Node* parent = nullptr;
Node* left = nullptr;
Node* right = nullptr;
T data{};
};
Node* root = nullptr;
public:
Node* get_root() const { return root; }
const Node* search(const T& _data);
void insert(const T& _data);
T find_max(Node* node);
T find_min(Node* node);
Node* delete_node(Node* node,T& data);
void print(Node* node);
};
template <typename T>
const typename BinaryTree<T>::Node* BinaryTree<T>::search(const T& _data)
{
Node* current = root;
while (current)
{
if (current->data == _data)
{
return current;
}
else if (current->data > _data)
{
current = current->left;
}
else if (current->data < _data)
{
current = current->right;
}
}
return nullptr;
}
template <typename T>
void BinaryTree<T>::insert(const T& _data)
{
Node* current = root;
if (current == nullptr)
{
root = new Node;
root->data = _data;
return;
}
while (current)
{
if (current->data == _data)
{
return;
}
if (_data > current->data)
{
if (current->right == nullptr)
{
Node* newNode = new Node();
newNode->data = _data;
current->right = newNode;
newNode->parent = current;
return;
}
current = current->right;
}
else if (_data < current->data)
{
if (current->left == nullptr)
{
Node* newNode = new Node();
newNode->data = _data;
current->left = newNode;
newNode->parent = current;
return;
}
current = current->left;
}
}
}
template <typename T>
void BinaryTree<T>::print(Node* node)
{
if (node != nullptr)
{
print(node->left);
std::cout << node->data << std::endl;
print(node->right);
}
}
//not used
template <typename T>
T BinaryTree<T>::find_max(Node* node)
{
if (node->right != NULL)
{
find_max(node->right);
}
else {
cout << node->data << std::endl;
}
return node->data;
}
template <typename T>
T BinaryTree<T>::find_min(Node* node)
{
if (node->left != NULL)
{
find_max(node->left);
}
else {
cout << node->data << std::endl;
}
return node->data;
}
template <typename T>
typename BinaryTree<T>::Node* BinaryTree<T>::delete_node(Node* node, T& _data)
{
if (node == NULL) {
return NULL;
}
else if (_data < node->data) {
node->left = delete_node(node->left, _data);
}
else if (_data > node->data) {
node->right = delete_node(node->right, _data);
}
else {
if (node->left == NULL) {
Node* temp = node->right;
delete node;
return temp;
}
else if (node->right == NULL) {
Node* temp = node->left;
delete node;
return temp;
}
else {
node->data = find_min(node->right);
node->right = delete_node(node->right, node->data);
}
}
return node;
}
int main()
{
BinaryTree<int> tree;
int numb{};
tree.insert(15);
tree.insert(11);
tree.insert(100);
tree.insert(16);
tree.insert(13);
tree.insert(18);
tree.insert(16);
tree.insert(10);
tree.print(tree.get_root());
cout << endl << endl;
cout << "Max: ";
tree.find_max(tree.get_root());
cout << endl << endl;
cout << "Min: ";
tree.find_min(tree.get_root());
tree.print(tree.get_root());
while (tree.search(numb)==nullptr) {
cout << "Choose Number To Delete: ";
cin >> numb;
}
cout << endl << endl;
tree.delete_node(tree.get_root(), numb);
tree.print(tree.get_root());
return 0;
}
相关文章:
- 为什么我的删除节点函数实际上没有删除节点?
- 为什么"delete"关键字不删除节点?
- 以递归方式从链表中删除节点
- 根据 Pugixml 中的子值删除节点
- 基于给定字符串数据类型的链表删除节点
- 在双向链表中给定节点之后删除节点
- 如何在单链列表 c++ 中正确删除节点
- 在BST堆中删除节点免错误
- 为什么我的打印功能之一删除节点
- 重载运算符>>从二叉树中删除节点
- 删除节点方法实际上不会删除二叉搜索树中的节点.C++
- C bST删除节点会破坏排序算法
- 删除节点并处理新的 nullptr 和链接节点
- 如何从链表中删除节点
- 如何在用于删除节点的函数中检查我的链表是否C++为空
- 从BST删除节点时出错
- 二叉树,从树中删除节点后将其删除
- 链接列表删除节点C
- 在二进制搜索树中删除节点
- 使用类从双向链表中删除节点