我写了一个小代码来检测二叉树中最大的数字,它工作得很好,很简单,它远远到最后一个节点(叶子以防)然后我只是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();
}
实际删除功能在//注释中,所以我可以运行prog。
答案 0 :(得分:3)
您正在删除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 case(因为如果子指针为null,你总是返回):
if (theRoot->rChildptr != NULL)
{
return Largest(theRoot->rChildptr);
}
T value = theRoot->data;
delete theRoot;
return value;
您还需要确保父节点仍然没有指向已删除的子节点(很难确切地看到发生了什么,因为您没有发布太多代码)。
答案 1 :(得分:2)
您不能简单地delete
您不想要的对象 - 您还必须删除用于查找您要删除的节点的参考。并且,如果节点有任何子节点,则必须将子节点重新附加到树的其他位置,以便它们保持可访问状态。
让它变得如此棘手的是你必须正确更新:父对被删除节点的引用;其中一个孩子&#39;已删除节点的一个子节点的指针;和来自已删除节点的两个子节点的父链接。如果您无序地执行更新,您将读取陈旧的指针并可能损坏内存,因此您必须等待删除节点,直到您不再需要节点内的任何其他引用,并且您已经从其他地方删除了到节点的引用。
<强>更新强>
别忘了&#34;最后一个正确的节点&#34;实际上可以成为树的根源:
5
4
3
2
1
5
是树中最大,最右边的节点,如果删除它,就会丢失整棵树。
除非你正在做一些我们在这里看不到的重新平衡;如果你是,请确保你也处理这种情况:
2
1
我们Wikipedia的朋友非常友好地分析了如何从二叉搜索树中删除节点:
- 删除一个叶子(没有子节点的节点):删除一个叶子很容易,因为我们可以简单地从树上删除它。
- 删除包含一个子节点的节点:删除节点并将其替换为其子节点。
- 删除具有两个子节点的节点:调用要删除的节点N.不要删除N.而是选择其有序后继节点 或者它的有序前导节点R.用N替换N的值 R的值,然后删除R.
您的删除代码必须处理所有这三种情况。不要忘记您正在删除的节点可能是树的根,而没有父节点。
答案 2 :(得分:0)
你可以发布整个程序,以便编译它。但基本上问题是,当theRoot-&gt; rChildptr为NULL时,你正在删除theRoot然后你的return语句试图返回指向无处的Root-&gt;数据。