Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 一次删除整个二叉搜索树_C++_Binary Search Tree - Fatal编程技术网

C++ 一次删除整个二叉搜索树

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

我一直在尝试实现deletebst函数,但我不知道为什么它不起作用,我认为它在逻辑上是正确的。任何人都可以告诉我,为什么我会出现运行时错误,我应该如何纠正它

  #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。虽然此代码片段可能会解决问题,包括如何以及为什么解决问题的解释,以提高您的文章质量。请记住,您是在将来为读者回答问题,而不仅仅是现在提问的人!请您的回答添加解释,并给出指示感谢你的回答。我修改了它,因为它实际上不起作用,但它帮助我开始了。