删除 BBST 中的节点
delete node in BBST
删除节点(值 8 或 2)不起作用。其余整个代码工作正常。甚至删除节点 4 也可以。我无法理解这个问题。
代码:在main()函数中,我从一维向量创建了一个平衡二进制搜索树。
#include <iostream>
#include <vector>
using namespace std;
class TNode
{
public:
TNode(){}
~TNode(){ std::cout <<"TNode destroyed" << endl; }
TNode *left;
TNode *right;
int data;
};
////////////////////////////////////////////////////////////////////
////////////////////////// TREE ////////////////////////////////
////////////////////////////////////////////////////////////////////
class TREE
{
public:
TREE(){}
~TREE(){}
TNode* createBBST(std::vector<int>& arr, int startIdx, int endIdx);
void preOrderTraverseBT(TNode *node);
void inOrderTraverseBT(TNode *node);
void postOrderTraverseBT(TNode *node);
TNode* searchBBST(TNode *rootnode, int data);
TNode* insertBBST(TNode *rootnode, int data);
void deleteBBST(TNode *rootnode, int data);
TNode* findPred(TNode *rootnode);
};
TNode* TREE::createBBST(std::vector<int>& arr, int startIdx, int endIdx)
{
//base-case
if(startIdx>endIdx)
return NULL;
/* Get the middle element and make it root */
TNode *root = new TNode;
int mid = (startIdx+endIdx)/2;
root->data = arr[mid];
/* Recursively construct the left subtree and make it left child of root */
root->left = createBBST(arr, startIdx, mid-1);
/* Recursively construct the right subtree and make it right child of root */
root->right = createBBST(arr, mid+1, endIdx);
return root;
}
void TREE::preOrderTraverseBT(TNode *node)
{
if(node==NULL)
return;
cout << node->data << " ";
preOrderTraverseBT(node->left);
preOrderTraverseBT(node->right);
return;
}
void TREE::inOrderTraverseBT(TNode *node)
{
if(node==NULL)
return;
inOrderTraverseBT(node->left);
cout << node->data << " ";
inOrderTraverseBT(node->right);
return;
}
TNode* TREE::searchBBST(TNode *rootnode, int data)
{
if(rootnode==NULL)
return NULL;
if(rootnode->data == data)
return rootnode;
else if(rootnode->data > data){
return searchBBST(rootnode->left, data);
}
else //if(rootnode->data < data)
return searchBBST(rootnode->right, data);
}
TNode* TREE::insertBBST(TNode *rootnode, int data)
{
if(rootnode->data >= data)
{
if(rootnode->left==NULL)
{
rootnode->left = new TNode;
rootnode->left->left=NULL; rootnode->left->right=NULL;
rootnode->left->data = data;
return rootnode->left;
}
else// if(rootnode->left!=NULL)
{
return insertBBST(rootnode->left, data);
}
}
else// if(rootnode->data < data)
{
if(rootnode->right==NULL)
{
rootnode->right = new TNode;
rootnode->right->left=NULL; rootnode->right->right=NULL;
rootnode->right->data = data;
return rootnode->right;
}
else// if(rootnode->right!=NULL)
{
return insertBBST(rootnode->right, data);
}
}
//
}
TNode* TREE::findPred(TNode *rootnode)
{
if(rootnode==NULL)
return rootnode;
return findPred(rootnode->right);
}
void TREE::deleteBBST(TNode *rootnode, int data)
{
cout << "Delete node : " << data << endl;
TNode *deletenode = searchBBST(rootnode, data);
TNode* temp = NULL;
if(deletenode->left==NULL && deletenode->right==NULL) /* 0 Child */
{
cout << "0 child..." << endl;
delete deletenode;
deletenode = NULL;
inOrderTraverseBT( rootnode );
cout << "ndeleted..."<<endl;
}
else if(deletenode->left!=NULL && deletenode->right==NULL) /* 1 Child */
{
cout << "1 child..." << endl;
//copy left child to its parent
temp = deletenode->left;
deletenode->data = temp->data;
deletenode->left = temp->left;
deletenode->right = temp->right;
}
else if(deletenode->left==NULL && deletenode->right!=NULL) /* 1 Child */
{
cout << "1 child..." << endl;
temp = deletenode->right;
deletenode->data = temp->data;
deletenode->right = temp->right;
deletenode->left = temp->left;
}
else /* 2 Children */
{
cout << "2 child..." << endl;
//find predecessor
TNode* pred = findPred(deletenode->left);
//if pred has no child
if(pred->left == NULL)
{
deletenode->data = pred->data;
}
else
{
//if pred has a left child
deletenode->data = pred->data;
pred->data = pred->left->data;
pred->left = pred->left->left;
}
delete pred;
pred = NULL;
}
//delete the old left child
delete temp;
temp = NULL;
}
////////////////////////////////////////////////////////////////////
////////////////////////// main ////////////////////////////////
////////////////////////////////////////////////////////////////////
int main(int argc, char const *argv[])
{
std::vector<int> vec(5);
for (int i = 0; i < vec.size(); ++i)
vec[i] = i;
TREE aTree;
TNode* root = aTree.createBBST(vec, 0, vec.size()-1);
//print the resulted BBST
aTree.inOrderTraverseBT( root );
//search a key
TNode* node = aTree.searchBBST(root, 3);
if(node != NULL)
cout << "node->data = " << node->data << endl;
else
cout << "Key not found..." << endl;
//insert
cout << "Insert node : 3" << endl;
aTree.insertBBST(root, 3);
aTree.inOrderTraverseBT( root );
cout << "Insert node : 8" << endl;
aTree.insertBBST(root, 8);
aTree.inOrderTraverseBT( root );
aTree.deleteBBST(root, 8);
// aTree.inOrderTraverseBT( root );
return 0;
}
在 TREE::deleteBBST
中,在"0 子"情况下(8 节点是):
delete deletenode;
deletenode = NULL;
但deletenode
是一个本地指针,它指向树中的节点。因此,您删除了节点,但树仍包含指向它的指针。后面的操作取消引用该指针,这会导致未定义的行为。
我建议您修改树以完全删除节点并更新指向它的节点,然后再删除它。
相关文章:
- 反向给定链表中的K节点
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- Boost Graph Library,修复节点大小
- C++A*算法并不总是在路径中具有目标节点
- 如何找到2个单链表的公共节点
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 为什么我的删除节点函数实际上没有删除节点?
- 我们可以删除链表中静态内存中的节点吗
- 如何在pugixml中获取节点的内部XML
- 为什么我们要为avl树实现返回一个指向节点的指针,而不是void函数
- C++RapidXml-使用first_node()遍历以修改XML文件中节点的值
- 为什么C++对链表中的下一个节点使用指针,而像 C# 或 Java 这样的语言只使用类 Node 的名称?
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- 节点 *temp; 和节点 *tmp = 新节点之间的差异
- 引擎节点:未定义的符号:_ZTV6Config
- 为什么"delete"关键字不删除节点?
- 如何使用发送数据包所花费的时间计算两个节点之间的距离?
- 如何按数字顺序插入链表节点?
- 为什么我的双向链表删除函数会删除多个节点?
- 删除 BBST 中的节点