在一个指针上使用 "delete" 会删除第二个指针(二叉搜索树)
Using "delete" on one pointer deletes a second pointer (Binary Search Tree)
这是一项作业;我不能使用智能指针。这是我感觉正在发生的事情的直观表示:
使用 Main.cpp 中的 myTree.remove(4)
后调试器中的树:
当我在二叉搜索树的 removeRec
函数中调用 delete temp
时,BTNode* x
从正确指向 2 到错误地分配给随机内存,如 temp
.显然,我希望 4 消失,让 BTNode* x
指向 2。我的 constructor/destructors 有问题吗?
独立 RemoveRec 函数:
bool BinarySearchTree::remove(int data){
return removeRec(root, data);
}
bool BinarySearchTree::removeRec(BTNode* &x, int data){
if (x == NULL){
return false;
}
else {
if (data < x->data){
return removeRec(x->left, data);
}
else if (data > x->data){
return removeRec(x->right, data);
}
else // Found item
{
BTNode* temp = x;
if (x->left == NULL){
x = x->right;
}
else if (x->right == NULL){
x = x->left;
}
else {
replaceParent(temp, temp->left);
}
delete temp;
return true;
}
}
}
BinarySearchTree.h:
#pragma once
#include <cstddef>
using namespace std;
#ifndef BTNODE_H
#define BTNODE_H
struct BTNode{
// Data Fields
int data;
BTNode* left;
BTNode* right;
// Constructor
BTNode(const int& the_data,
BTNode* left_val = NULL,
BTNode* right_val = NULL) :
data(the_data), left(left_val), right(right_val) {}
// Destructor (to avoid warning message)
~BTNode() {
if (this->left){
delete this->left;
}
if (this->right){
delete this->right;
}
}
};
#endif
#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H
class BinarySearchTree
{
private:
BTNode* root;
public:
// BST Constructor / Deconstructor
BinarySearchTree() : root(NULL){}
BinarySearchTree(const int& the_data,
const BinarySearchTree& left_child = BinarySearchTree(),
const BinarySearchTree& right_child = BinarySearchTree()) :
root(new BTNode(the_data, left_child.root, right_child.root)){}
virtual ~BinarySearchTree(){}
// Interface Functions ----------------------
bool add(int data);
bool remove(int data);
void clear();
// My Functions -----------------------------
bool addRec(BTNode* &x, int data);
bool removeRec(BTNode* &x, int data);
bool Search(BTNode* root, int data);
void replaceParent(BTNode* &old_root, BTNode* &local_root);
};
#endif
BinarySearchTree.cpp:
#pragma once
#include "BinarySearchTree.h"
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>
// Interface Functions ----------------------
bool BinarySearchTree::add(int data){
return addRec(root, data);
}
bool BinarySearchTree::addRec(BTNode* &x, int data){
if (x == NULL){
x = new BTNode(data);
return true;
}
if (data == x->data){
return false;
}
if (x != NULL){
if (data < x->data){
return addRec(x->left, data);
}
if (data > x->data){
return addRec(x->right, data);
}
}
}
bool BinarySearchTree::remove(int data){
return removeRec(root, data);
}
bool BinarySearchTree::removeRec(BTNode* &x, int data){
if (x == NULL){
return false;
}
else {
if (data < x->data){
return removeRec(x->left, data);
}
else if (data > x->data){
return removeRec(x->right, data);
}
else // Found item
{
BTNode* temp = x;
if (x->left == NULL){
x = x->right;
}
else if (x->right == NULL){
x = x->left;
}
else {
replaceParent(temp, temp->left);
}
delete temp;
return true;
}
}
}
void BinarySearchTree::replaceParent(BTNode* &old_root, BTNode* &local_root){
if (local_root->right == NULL){
replaceParent(old_root, local_root->right);
}
else{
old_root->data = local_root->data;
old_root = local_root;
local_root = local_root->left;
}
}
void BinarySearchTree::clear(){
delete root;
root = NULL;
}
// My Functions -----------------------------
bool BinarySearchTree::Search(BTNode* root, int data) {
if (root == NULL) {
return false;
}
else if (root->data == data) {
return true;
}
else if (data < root->data) { // had <= instead
return Search(root->left, data);
}
else if (data > root->data) { // had no "if"
return Search(root->right, data);
}
}
Main.cpp
#include <stdio.h>
#include "BinarySearchTree.h"
using namespace std;
int main(){
BinarySearchTree myTree;
myTree.add(6);
myTree.add(4);
myTree.add(8);
myTree.add(2);
myTree.remove(4);
}
从树中删除一个节点后,您将指向它的节点重新分配为现在指向 child。在本例中,它从 6->4->2
变为 6->2
。但是,当你删除节点 4
时,它仍然指向 2
。然后 4
的析构函数杀死节点 2
.
解决方案是在删除节点之前将节点中的 left
和 right
指针都设置为 NULL
。
这是一项作业;我不能使用智能指针。这是我感觉正在发生的事情的直观表示:
使用 Main.cpp 中的 myTree.remove(4)
后调试器中的树:
当我在二叉搜索树的 removeRec
函数中调用 delete temp
时,BTNode* x
从正确指向 2 到错误地分配给随机内存,如 temp
.显然,我希望 4 消失,让 BTNode* x
指向 2。我的 constructor/destructors 有问题吗?
独立 RemoveRec 函数:
bool BinarySearchTree::remove(int data){
return removeRec(root, data);
}
bool BinarySearchTree::removeRec(BTNode* &x, int data){
if (x == NULL){
return false;
}
else {
if (data < x->data){
return removeRec(x->left, data);
}
else if (data > x->data){
return removeRec(x->right, data);
}
else // Found item
{
BTNode* temp = x;
if (x->left == NULL){
x = x->right;
}
else if (x->right == NULL){
x = x->left;
}
else {
replaceParent(temp, temp->left);
}
delete temp;
return true;
}
}
}
BinarySearchTree.h:
#pragma once
#include <cstddef>
using namespace std;
#ifndef BTNODE_H
#define BTNODE_H
struct BTNode{
// Data Fields
int data;
BTNode* left;
BTNode* right;
// Constructor
BTNode(const int& the_data,
BTNode* left_val = NULL,
BTNode* right_val = NULL) :
data(the_data), left(left_val), right(right_val) {}
// Destructor (to avoid warning message)
~BTNode() {
if (this->left){
delete this->left;
}
if (this->right){
delete this->right;
}
}
};
#endif
#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H
class BinarySearchTree
{
private:
BTNode* root;
public:
// BST Constructor / Deconstructor
BinarySearchTree() : root(NULL){}
BinarySearchTree(const int& the_data,
const BinarySearchTree& left_child = BinarySearchTree(),
const BinarySearchTree& right_child = BinarySearchTree()) :
root(new BTNode(the_data, left_child.root, right_child.root)){}
virtual ~BinarySearchTree(){}
// Interface Functions ----------------------
bool add(int data);
bool remove(int data);
void clear();
// My Functions -----------------------------
bool addRec(BTNode* &x, int data);
bool removeRec(BTNode* &x, int data);
bool Search(BTNode* root, int data);
void replaceParent(BTNode* &old_root, BTNode* &local_root);
};
#endif
BinarySearchTree.cpp:
#pragma once
#include "BinarySearchTree.h"
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>
// Interface Functions ----------------------
bool BinarySearchTree::add(int data){
return addRec(root, data);
}
bool BinarySearchTree::addRec(BTNode* &x, int data){
if (x == NULL){
x = new BTNode(data);
return true;
}
if (data == x->data){
return false;
}
if (x != NULL){
if (data < x->data){
return addRec(x->left, data);
}
if (data > x->data){
return addRec(x->right, data);
}
}
}
bool BinarySearchTree::remove(int data){
return removeRec(root, data);
}
bool BinarySearchTree::removeRec(BTNode* &x, int data){
if (x == NULL){
return false;
}
else {
if (data < x->data){
return removeRec(x->left, data);
}
else if (data > x->data){
return removeRec(x->right, data);
}
else // Found item
{
BTNode* temp = x;
if (x->left == NULL){
x = x->right;
}
else if (x->right == NULL){
x = x->left;
}
else {
replaceParent(temp, temp->left);
}
delete temp;
return true;
}
}
}
void BinarySearchTree::replaceParent(BTNode* &old_root, BTNode* &local_root){
if (local_root->right == NULL){
replaceParent(old_root, local_root->right);
}
else{
old_root->data = local_root->data;
old_root = local_root;
local_root = local_root->left;
}
}
void BinarySearchTree::clear(){
delete root;
root = NULL;
}
// My Functions -----------------------------
bool BinarySearchTree::Search(BTNode* root, int data) {
if (root == NULL) {
return false;
}
else if (root->data == data) {
return true;
}
else if (data < root->data) { // had <= instead
return Search(root->left, data);
}
else if (data > root->data) { // had no "if"
return Search(root->right, data);
}
}
Main.cpp
#include <stdio.h>
#include "BinarySearchTree.h"
using namespace std;
int main(){
BinarySearchTree myTree;
myTree.add(6);
myTree.add(4);
myTree.add(8);
myTree.add(2);
myTree.remove(4);
}
从树中删除一个节点后,您将指向它的节点重新分配为现在指向 child。在本例中,它从 6->4->2
变为 6->2
。但是,当你删除节点 4
时,它仍然指向 2
。然后 4
的析构函数杀死节点 2
.
解决方案是在删除节点之前将节点中的 left
和 right
指针都设置为 NULL
。