C++ 一次删除整个二叉搜索树
我一直在尝试实现deletebst函数,但我不知道为什么它不起作用,我认为它在逻辑上是正确的。任何人都可以告诉我,为什么我会出现运行时错误,我应该如何纠正它C++ 一次删除整个二叉搜索树,c++,binary-search-tree,C++,Binary Search Tree,我一直在尝试实现deletebst函数,但我不知道为什么它不起作用,我认为它在逻辑上是正确的。任何人都可以告诉我,为什么我会出现运行时错误,我应该如何纠正它 #include <iostream> using namespace std; class node{ public: int data; node *right; node *left; node(){ data=0; right=NULL; left=NULL; } }; c
#include <iostream>
using namespace std;
class node{
public:
int data;
node *right;
node *left;
node(){
data=0;
right=NULL;
left=NULL;
}
};
class tree{
node *head;
int maxheight;
public:
tree(){head=0;maxheight=-1;}
bool deletenode(int key,node* root);
int get_height(){return maxheight;}
void insert(int key);
void pre_display(node* root);
void delete_tree(node *root);
node* get_head(){return head;}
};
void tree::insert(int key){
node *current=head;
node *newnode=new node;
if(newnode==NULL)
throw(key);
newnode->data=key;
int height=0;
if(head==0){
head=newnode;
}
else
{
while(1){
if(current->right==NULL && current->data < newnode->data)
{
current->right=newnode;
height++;
break;
}
else if(current->left==NULL && current->data > newnode->data)
{
current->left=newnode;
height++;
break;
}
else if(current->right!=NULL && current->data < newnode->data)
{
current=current->right;
height++;
}
else if(current->left!=NULL && current->data > newnode->data)
{
current=current->left;
height++;
}
}
}
if(height>maxheight)
maxheight=height;
}
void tree::pre_display(node *root){
if(root!=NULL)
{
cout<<root->data<<" ";
pre_display(root->left);
pre_display(root->right);
}
}
void tree::delete_tree(node *root){
if(root!=NULL)
{
delete_tree(root->left);
delete_tree(root->right);
delete(root);
if(root->left!=NULL)
root->left=NULL;
if(root->right!=NULL)
root->right=NULL;
root=NULL;
}
}
int main(){
tree BST;
int arr[9]={17,9,23,5,11,21,27,20,22},i=0;
for(i=0;i<9;i++)
BST.insert(arr[i]);
BST.pre_display(BST.get_head());
cout<<endl;
BST.delete_tree(BST.get_head());
BST.pre_display(BST.get_head());
cout<<endl;
system("pause");
return 0;
}
#包括
使用名称空间std;
类节点{
公众:
int数据;
节点*右;
节点*左;
节点(){
数据=0;
右=空;
左=空;
}
};
类树{
节点*头;
int最大高度;
公众:
tree(){head=0;maxheight=-1;}
bool deletenode(int键,节点*根);
int get_height(){return maxheight;}
无效插入(int键);
无效预显示(节点*根);
void delete_树(节点*根);
节点*get_head(){return head;}
};
无效树::插入(int键){
节点*电流=头部;
node*newnode=新节点;
if(newnode==NULL)
投掷(钥匙);
新建节点->数据=键;
整数高度=0;
如果(头==0){
头=新节点;
}
其他的
{
而(1){
如果(当前->右侧==NULL&¤t->datadata)
{
当前->右=新节点;
高度++;
打破
}
else if(当前->左==NULL&¤t->data>newnode->data)
{
当前->左=新节点;
高度++;
打破
}
else if(当前->右侧!=NULL&¤t->datadata)
{
当前=当前->右侧;
高度++;
}
else if(当前->左!=NULL&¤t->data>newnode->data)
{
当前=当前->左侧;
高度++;
}
}
}
如果(高度>最大高度)
最大高度=高度;
}
void tree::pre_显示(节点*根){
if(root!=NULL)
{
coutleft);
删除_树(根->右);
删除(根);
如果(根->左!=NULL)
根->左=空;
如果(根->右!=NULL)
root->right=NULL;
root=NULL;
}
}
int main(){
树BST;
int arr[9]={17,9,23,5,11,21,27,20,22},i=0;
对于(i=0;i删除后不应从root读取。请向下移动删除树中的delete(root)
行。
void tree::delete_tree(node *root){
if(root!=NULL)
{
delete_tree(root->left);
delete_tree(root->right);
delete(root);
if(root->left!=NULL)
root->left=NULL;
if(root->right!=NULL)
root->right=NULL;
root=NULL;
}
}
删除后,您正在访问根变量
你也打电话吗
BST.delete_tree(BST.get_head());
BST.pre_display(BST.get_head());
删除树后预显示。删除树删除树后还应将BST.head设置为空
还有一个commission.BST是tree类型。它已经有一个head成员变量指示根节点。因此delete_tree/pre_display根本不需要任何参数。问题在于:
delete_tree(root->left);
delete_tree(root->right);
delete(root);
if(root->left!=NULL)
root->left=NULL;
if(root->right!=NULL)
root->right=NULL;
root=NULL;
您正在尝试将NULL分配给root的成员:
root->left=NULL;
已被删除。无需执行此操作,因为您已经在delete_tree(root->left)中释放内存;
递归删除左、右子树,您的树将被删除,操作非常简单:
void delete(node *root){
// If node is empty, don't bother
if (root == NULL) { return; }
// Delete subtrees
delete(root->left);
delete(root->right);
// Delete current node
free(root);
root = NULL;
}
您可以通过以下方式删除:
//这是清洁的功能:
void cleantree(tree *root){
if(root->left!=NULL)cleantree(root->left);
if(root->right!=NULL)cleantree(root->right);
delete root;}
//这就是我们称之为清洁功能的地方:
cleantree(a);
a=NULL;
//其中“a”是指向树根的指针。简短回答:节点描述符的实现缺少正确的显式析构函数实现(编译器生成的默认值将通过调用delete操作符来使用:调用析构函数并释放堆上分配的空间)-在这里,我建议使用递归性来清除对兄弟姐妹的引用
template <class T> void Tree<T>::destroy(Noeud<T> ** r){
if(*r){
if(!(*r)->left && !(*r)->right){ //a node having no child
delete *r; *r=NULL;
}else if((*r)->left && (*r)->right){ //a node having two childs
destroy(&(*r)->left); //destroy the left tree
destroy(&(*r)->right); //destroy the right tree
destroy(r); //destroy the node
}else if((*r)->left){ //a node has only left child
destroy(&(*r)->left); //destroy the left tree
destroy(r); //destroy the node
}else if((*r)->right){ //a node has only right child
destroy(&(*r)->right); //destroy the right tree
destroy(r); //destroy the node
}
}
}
//in function main()
int main(){
Tree<int> a(5); // 'a' is a tree of int type with a root value equal 5
a.add(2);a.add(7);a.add(6);a.add(-1);a.add(10); // insert values into the tree
a.destroy(&a.root); //destroy the tree
}
模板无效树::销毁(Noeud**r){
如果(*r){
如果(!(*r)->左&&(*r)->右){//一个没有子节点的节点
删除*r;*r=NULL;
}else如果((*r)->left&(*r)->right){//一个节点有两个子节点
销毁(&(*r)->左);//销毁左树
销毁(&(*r)->右);//销毁正确的树
销毁(r);//销毁节点
}else如果((*r)->left){//节点只剩下子节点
销毁(&(*r)->左);//销毁左树
销毁(r);//销毁节点
}else如果((*r)->right){//节点只有正确的子节点
销毁(&(*r)->右);//销毁正确的树
销毁(r);//销毁节点
}
}
}
//在函数main()中
int main(){
树a(5);//“a”是一个int类型的树,根值等于5
a、 add(2);a.add(7);a.add(6);a.add(-1);a.add(10);//在树中插入值
a、 销毁(&a.root);//销毁树
}
我是否可以在delete\u tree更改delete\u tree的函数中添加将null赋值给head的实现,使其不包含任何参数。使用私有iDeleteInternal进行递归调用。因此delete\u tree调用iDeleteInternal,然后在返回之前将head设置为null,但如果我这样做,正如您之前所说,在maki之后删除ng pointers null,这是否意味着我正在丢失分配内存的位置,然后我正在删除null指针?但是如果我不写以下语句:root->left=null;我得到了错误。@Zohaib我对此表示怀疑。删除(root)后你删除了所有内容吗?我收到了许多正在打印的地址和运行时错误。请勾选一些答案。这不仅仅是为了分数(不管怎样,谁会来这里…?),但对于有同样问题的人来说,这是一种直接找到正确解决方案的方法。但是,如果我这样做,正如你所说,这并不意味着我正在失去分配内存的位置,然后我正在删除空指针?你还应该删除在该函数中设置为空的行。没有必要给我写信即将被删除的mory。虽然此代码片段可能会解决问题,包括如何以及为什么解决问题的解释,以提高您的文章质量。请记住,您是在将来为读者回答问题,而不仅仅是现在提问的人!请您的回答添加解释,并给出指示感谢你的回答。我修改了它,因为它实际上不起作用,但它帮助我开始了。