C++ 从二叉搜索树中删除节点时遇到困难
我正在创建一个二元搜索树,它需要能够删除一个节点,如果该节点被正确删除,则返回true;如果该值在树中不存在,则返回false。我这样做是因为我需要删除多个数字,并且我想创建一个while循环来删除所有的数字。例如,一棵树具有以下整数:{79、83、147、71、95、49、15、191}。另一棵树有以下整数{26,79,144,88,147,200,90}。我的任务是找到树1中的所有元素,这些元素在树2中,并将它们从树1中删除(在本例中为79和147)。我想创建一个循环,通过树2中的所有数字运行,并从树1中搜索和删除。以下是我到目前为止关于remove node函数的内容(假设已经构建并填充了树): 节点h:C++ 从二叉搜索树中删除节点时遇到困难,c++,recursion,binary-search-tree,C++,Recursion,Binary Search Tree,我正在创建一个二元搜索树,它需要能够删除一个节点,如果该节点被正确删除,则返回true;如果该值在树中不存在,则返回false。我这样做是因为我需要删除多个数字,并且我想创建一个while循环来删除所有的数字。例如,一棵树具有以下整数:{79、83、147、71、95、49、15、191}。另一棵树有以下整数{26,79,144,88,147,200,90}。我的任务是找到树1中的所有元素,这些元素在树2中,并将它们从树1中删除(在本例中为79和147)。我想创建一个循环,通过树2中的所有数字运
template<class ItemType>
class Node {
public:
ItemType data;
Node * left;
Node * right;
//Constructors / Destructors
Node ();
Node ( ItemType inData );
~Node ();
};
//--------------------------------------------------------------//
//-- Constructor / Destructor --//
//--------------------------------------------------------------//
/** Standard Constructor */
template<class ItemType>
Node<ItemType>::Node () {
left = right = NULL;
}
/** Overload Constructor */
template<class ItemType>
Node<ItemType>::Node ( ItemType inData ) {
data = inData;
left = right = NULL;
}
/** Standard Destructor */
template<class ItemType>
Node<ItemType>::~Node () {
right = left = NULL;
}
模板
类节点{
公众:
项目类型数据;
节点*左;
节点*右;
//构造函数/析构函数
节点();
节点(ItemType inData);
~Node();
};
//--------------------------------------------------------------//
//--构造函数/析构函数--//
//--------------------------------------------------------------//
/**标准构造器*/
模板
Node::Node(){
左=右=空;
}
/**重载构造函数*/
模板
节点::节点(ItemType inData){
数据=inData;
左=右=空;
}
/**标准析构函数*/
模板
节点::~节点(){
右=左=空;
}
从Source.cpp:
Tree2.postorder_print ();
int ridOf = 79;
if (Tree2.remove ( ridOf )) {
Tree2.postorder_print ();
cout << endl << "Number of Nodes: " << Tree2.get_num_of_nodes () << endl;
cout << "Height: " << Tree2.get_tree_height () << endl << endl;
}
Tree2.postorder_print();
int-ridOf=79;
如果(Tree2.remove(ridOf)){
Tree2.postorder_print();
正确;
Node*tempLeft=新节点;
tempLeft=inRoot->left;
inRoot=nullNode;
inRoot=温度;
temp->left=tempLeft;
临时->右侧=临时右侧;
返回true;
}
//如果inRoot有一个子项
否则{
//如果inRoot离开了孩子
如果(inRoot->right==NULL){
节点*temp=新节点;
温度=根->左;
inRoot=nullNode;
inRoot=温度;
返回true;
}
//如果inRoot有正确的子对象
否则{
节点*temp=新节点;
temp=inRoot->right;
inRoot=nullNode;
inRoot=温度;
返回true;
}
}
}
//如果不是,则查看包含数据的节点的toRemove是否小于inRoot,并执行递归操作
else if(删除data){
删除辅助对象(在根->左,删除);
}//如果结束(删除data)
//查看toRemove是否大于inRoot并执行递归操作
否则如果(删除>根目录->数据){
删除辅助对象(在根->右侧,删除);
}//别有用心
//如果找不到数据,则返回false
否则返回false;
}
我的一些结果是不同的,都是错误的。一个结果是无限循环不断地反复打印树。另一个结果是它执行了删除操作,看起来很成功,但如果查看两个打印输出,它们是相同的,并且节点未被删除(如果返回false,则不应再次打印,但确实如此)。然后,第三个结果发生在第二次打印预订单期间。它会中断并在空节点上停止,但左右两侧的数据都显示“无法读取内存”。我做错了什么?我想不出来。我的所有其他树函数(包括预订单打印),直到我尝试删除一个节点
只是想澄清一点,我的remove\u helper函数有问题。因此,我可以继续从Tree1中删除Tree2中存在的节点 你要做的是在两棵树之间倒交叉。可以通过创建一个带有两个参数的函数来实现这一点。一个参数是要从中删除内容的树(tree1),另一个参数是要检查的树(tree2)
然后在函数中使用递归检查树2。对于您取出的每个元素,您使用该元素来搜索它是否存在于树1中(在这种情况下,还可以删除它)。然后继续在tree1中搜索tree2中的每个节点,直到遍历tree2中的每个元素。
remove\u helper
正在尝试更改inRoot
参数的值。但是,inRoot
是按值传递的,因此在函数中所做的任何更改都不会反映在调用函数中
将remove\u helper
函数更改为通过引用获取inRoot
,然后它将能够修改调用函数中使用的参数值:
template<class ItemType>
bool BTree<ItemType>::remove_helper (Node<ItemType> * &inRoot, ItemType toRemove) {
您正在分配一些内存并在tempRight
中指向它,然后立即将tempRight
设置为其他内容。这是内存泄漏,是不必要的-您不需要为每个指针分配内存。
将其更改为:
Node<ItemType> * tempRight = inRoot->right;
Node*tempRight=inRoot->right;
好的,@TheDark提供了大量帮助,这是我的删除辅助功能:
template<class ItemType>
bool BTree<ItemType>::remove_helper (Node<ItemType> * &inRoot, ItemType toRemove) {
//if this is the node with the data
if (inRoot->data == toRemove) {
//if inRoot has No Children
if (inRoot->left == NULL && inRoot->right == NULL ) {
inRoot = NULL;
std::cout << "one" << std::endl;
return true;
}
//if inRoot has 2 Children
else if (inRoot->left != NULL && inRoot->right != NULL) {
inRoot->data = return_max_value ( inRoot->left )->data;
remove_helper (inRoot->left,inRoot->data);
std::cout << "two" << std::endl;
return true;
}
//if inRoot has 1 child
else {
std::cout << "zero" << std::endl;
//if inRoot has left child
if (inRoot->right == NULL) {
Node<ItemType> * temp = new Node < ItemType >;
temp = inRoot->left;
inRoot = NULL;
inRoot = temp;
return true;
}
//if inRoot has right child
else {
Node<ItemType> * temp = new Node < ItemType >;
temp = inRoot->right;
inRoot = NULL;
inRoot = temp;
return true;
}
}
}
//If not the node with the data See if toRemove is less than inRoot and perform recursive action
else if ( toRemove < inRoot->data ) {
remove_helper ( inRoot->left, toRemove );
} //end if (toRemove < inRoot->data)
//See if toRemove is greater than inRoot and perform recursive action
else if ( toRemove > inRoot->data) {
remove_helper ( inRoot->right, toRemove );
}// end of else
//return false if data cannot be found
else return false;
}
模板
boolbtree::remove\u helper(Node*&inRoot,ItemType-toRemove){
//如果这是包含数据的节点
如果(inRoot->data==toRemove){
//如果inRoot没有孩子
如果(inRoot->left==NULL&&inRoot->right==NULL){
inRoot=NULL;
std::cout right!=NULL){
inRoot->data=返回最大值(inRoot->left)->数据;
删除辅助对象(inRoot->left,inRoot->data);
std::cout;
temp=inRoot->right;
inRoot=NULL;
inRoot=温度;
返回true;
}
}
}
//如果不是,则查看包含数据的节点的toRemove是否小于inRoot,并执行递归操作
否则如果(删除数据
Node<ItemType> * tempRight = new Node < ItemType >;
tempRight = inRoot->right;
Node<ItemType> * tempRight = inRoot->right;
template<class ItemType>
bool BTree<ItemType>::remove_helper (Node<ItemType> * &inRoot, ItemType toRemove) {
//if this is the node with the data
if (inRoot->data == toRemove) {
//if inRoot has No Children
if (inRoot->left == NULL && inRoot->right == NULL ) {
inRoot = NULL;
std::cout << "one" << std::endl;
return true;
}
//if inRoot has 2 Children
else if (inRoot->left != NULL && inRoot->right != NULL) {
inRoot->data = return_max_value ( inRoot->left )->data;
remove_helper (inRoot->left,inRoot->data);
std::cout << "two" << std::endl;
return true;
}
//if inRoot has 1 child
else {
std::cout << "zero" << std::endl;
//if inRoot has left child
if (inRoot->right == NULL) {
Node<ItemType> * temp = new Node < ItemType >;
temp = inRoot->left;
inRoot = NULL;
inRoot = temp;
return true;
}
//if inRoot has right child
else {
Node<ItemType> * temp = new Node < ItemType >;
temp = inRoot->right;
inRoot = NULL;
inRoot = temp;
return true;
}
}
}
//If not the node with the data See if toRemove is less than inRoot and perform recursive action
else if ( toRemove < inRoot->data ) {
remove_helper ( inRoot->left, toRemove );
} //end if (toRemove < inRoot->data)
//See if toRemove is greater than inRoot and perform recursive action
else if ( toRemove > inRoot->data) {
remove_helper ( inRoot->right, toRemove );
}// end of else
//return false if data cannot be found
else return false;
}