[英]Deleting from Binary Tree error
我写了一个小代码来检测二叉树中的最大数字,它工作得很好,很简单,它可以深入到最后一个右节点(以防万一),然后我cout <<它,现在我会我想删除它,但我只想删除我从搜索中得到的号码,但是我的编程序在运行它后崩溃,列出了树,得到了该号码,删除并尝试再次列出它。
这是我的搜索:
T Remove( Node* theRoot)
{
if ( root == NULL )
{
cout<<"There is no tree";
return -1;
}
if (theRoot->rChildptr != NULL)
return Largest(theRoot->rChildptr);
else
delete theRoot;
return theRoot->data;
}
这是完整的代码:
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
template<class T>
class BinaryTree
{
struct Node
{
T data;
Node* lChildptr;
Node* rChildptr;
Node(T dataNew)
{
data = dataNew;
lChildptr = NULL;
rChildptr = NULL;
}
};
private:
Node* root;
void Insert(T newData, Node* &theRoot)
{
if(theRoot == NULL)
{
theRoot = new Node(newData);
return;
}
if(newData < theRoot->data)
Insert(newData, theRoot->lChildptr);
else
Insert(newData, theRoot->rChildptr);
}
void PrintTree(Node* theRoot)
{
if(theRoot != NULL)
{
PrintTree(theRoot->lChildptr);
cout<< theRoot->data<<" \n";
PrintTree(theRoot->rChildptr);
}
}
T Largest( Node* theRoot)
{
if ( root == NULL )
{
cout<<"There is no tree";
return -1;
}
if (theRoot->rChildptr != NULL)
return Largest(theRoot->rChildptr);
else
delete theRoot;
return theRoot->data;
}
T Remove(Node* theRoot)
{
if ( root == NULL )
{
cout<<"There is no tree";
return -1;
}
if (theRoot->rChildptr != NULL)
return Largest(theRoot->rChildptr);
else
delete theRoot;
return ;
};
public:
BinaryTree()
{
root = NULL;
}
void AddItem(T newData)
{
Insert(newData, root);
}
void PrintTree()
{
PrintTree(root);
}
T Largest()
{
return Largest(root);
}
//void Remove()
//{
// Remove(root);
//}
};
int main()
{
BinaryTree<int> *myBT = new BinaryTree<int>();
myBT->AddItem(2);
myBT->AddItem(20);
myBT->AddItem(5);
myBT->AddItem(1);
myBT->AddItem(10);
myBT->AddItem(15);
//for(int i = 0; i < 10; i++) //randommal tolti fel
//myBT->AddItem(rand() % 100);
cout << "BinaryTree:" << endl; //kilistazaa a fat
myBT->PrintTree();
cout << "Largest element: " << myBT->Largest() << endl; //visszaadja a legnagyobb elemet
//myBT->Remove();
myBT->PrintTree();
}
实际的删除功能在//注释中,因此我可以运行该编。
您正在删除theRoot
,然后尝试取消引用它。 如果要返回存储在节点中的值,则需要先进行本地复制,如下所示:
T value = theRoot->data;
delete theRoot;
return value;
return thetRoot->data;
行是否打算成为else语句的一部分? 如果是这样,您需要像这样在其周围添加括号:
if (theRoot->rChildptr != NULL)
{
return Largest(theRoot->rChildptr);
}
else
{
T value = theRoot->data;
delete theRoot;
return value;
}
或简单地完全删除else情况(因为如果子指针为null则总是返回):
if (theRoot->rChildptr != NULL)
{
return Largest(theRoot->rChildptr);
}
T value = theRoot->data;
delete theRoot;
return value;
您还需要确保父节点仍未指向已删除的子节点(由于您未发布太多代码,因此很难确切地了解正在发生的情况)。
您不能简单地delete
不需要的对象-您还必须删除用于查找要删除的节点的引用。 而且,如果节点有任何子节点,则必须将子节点重新连接到树的其他位置,以使它们保持可访问性。
使它变得如此棘手的是,您必须正确更新:父级对要删除的节点的引用; 被删除节点之一的“子”指针之一; 以及来自已删除节点的两个子节点的父节点链接。 如果执行更新外的顺序,你会读到一个陈旧的指针,也许损坏内存,所以你必须等待,直到你不需要从节点内的任意多个引用删除节点,你已经删除引用到其他地方的节点。
更新
不要忘记“最后一个正确的节点”实际上可以成为树的根:
5
4
3
2
1
5
是树中最大,最右边的节点,如果删除它,则会丢失整个树。
除非您要进行一些重新平衡,否则我们不会在这里看到。 如果是这样,请确保您也处理这种情况:
2
1
我们的Wikipedia朋友非常善于分析如何从二叉搜索树中删除节点:
- 删除叶子(没有子节点):删除叶子很容易,因为我们可以简单地将其从树中删除。
- 删除带有一个子节点的节点:删除该节点并将其替换为其子节点。
- 删除具有两个子节点的节点:调用要删除的节点N。不要删除N。而是选择其有序后继节点或有序前任节点R。将N的值替换为R的值,然后删除R。
您的删除代码必须处理所有这三种情况。 不要忘记,您要删除的节点可能是树的根,并且没有父节点。
您可以发布整个程序,以便对其进行编译。 但是基本上的问题是,当theRoot-> rChildptr为NULL时,您将删除theRoot,然后您的return语句将尝试返回指向无处的theRoot-> data。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.