C++ 为什么我的seg故障(核心转储)与此?

C++ 为什么我的seg故障(核心转储)与此?,c++,binary-tree,binary-search-tree,C++,Binary Tree,Binary Search Tree,所以我试图写一个二叉搜索树,这个擦除函数给了我一个seg错误。我的节点类有一个临时数据,以及指向左、右子节点和父节点的指针。 我有一个函数find(temp key),它将一个节点*返回给保存key作为其数据的节点。所以在我看来,我有 Node<temp>* p = bTree->find(key); Node*p=bTree->find(键); find函数起作用,但当我这样做时 b树->擦除(p); 然后打印我的结果,iit编译,但我有一个seg错误。请帮忙,谢谢 te

所以我试图写一个二叉搜索树,这个擦除函数给了我一个seg错误。我的节点类有一个临时数据,以及指向左、右子节点和父节点的指针。 我有一个函数find(temp key),它将一个节点*返回给保存key作为其数据的节点。所以在我看来,我有

Node<temp>* p = bTree->find(key);
Node*p=bTree->find(键);
find函数起作用,但当我这样做时 b树->擦除(p); 然后打印我的结果,iit编译,但我有一个seg错误。请帮忙,谢谢

template <typename temp>
void BinTree<temp>::erase(Node<temp>* n){

  if(!n->lChild && !n->rChild){ //n has no children
    delete n;
    n = nullptr;
  }

  else if(n->lChild && n->rChild){ //n has two children
    Node<temp>* p = n->rChild;
    while(p->lChild)
        p = p->lChild; //p will be n's successor
    n->data = p->data; //set the data to that of the successor
    if(p->rChild){  //take care of p's right child if it has one
        p->parent->lChild = p->rChild;
        p->rChild->parent = p->parent;
    }
    delete p;
    p = nullptr;
  }

  else{ //n only has one child
    if(n->parent){
        if(n->data < n->parent->data){ //n is a left child
            if(n->lChild){ //n has only a left child
                n->lChild->parent = n->parent;
                n->parent->lChild = n->lChild;
            }
            else{ //n has only a right child
                n->rChild->parent = n->parent;
                n->parent->lChild = n->rChild;
            }
        }
        else{ //n is a right child
            if(n->lChild){ //n has only a left child
                n->lChild->parent = n->parent;
                n->parent->rChild = n->lChild;
            }
            else{ //n has only a right child
                n->rChild->parent = n->parent;
                n->parent->rChild = n->rChild;
            }
        }
    }
    else{ //n is  the root and has no parent, but still only has one child
        if(n->lChild)
            root = n->lChild;
        else
            root = n->rChild;
    }
    delete n;
    n = nullptr;
  }
}
模板
void BinTree::擦除(节点*n){
如果(!n->lChild&&!n->rChild){//n没有子项
删除n;
n=空PTR;
}
如果(n->lChild&&n->rChild){//n有两个子项,则为else
节点*p=n->rChild;
while(p->lChild)
p=p->lChild;//p将是n的继任者
n->data=p->data;//设置后继数据
if(p->rChild){//照顾p的右孩子(如果有)
p->parent->lChild=p->rChild;
p->rChild->parent=p->parent;
}
删除p;
p=nullptr;
}
否则{//n只有一个孩子
如果(n->parent){
如果(n->dataparent->data){//n是左子级
如果(n->lChild){//n只剩下一个子项
n->lChild->parent=n->parent;
n->parent->lChild=n->lChild;
}
否则{//n只有一个合适的孩子
n->rChild->parent=n->parent;
n->parent->lChild=n->rChild;
}
}
否则{//n是一个正确的孩子
如果(n->lChild){//n只剩下一个子项
n->lChild->parent=n->parent;
n->parent->rChild=n->lChild;
}
否则{//n只有一个合适的孩子
n->rChild->parent=n->parent;
n->parent->rChild=n->rChild;
}
}
}
else{//n是根,没有父级,但仍然只有一个子级
如果(n->lChild)
root=n->lChild;
其他的
root=n->rChild;
}
删除n;
n=空PTR;
}
}

您对指针有严重误解

重要的不仅仅是要删除的节点本身,还有哪些其他指针指向该节点

例如,查看erase()中的第一个案例:


删除节点n。但是n的父级仍然存储指向n的指针…

您调试了程序吗?欢迎使用堆栈溢出!听起来您可能需要学习如何使用调试器逐步完成代码。有了一个好的调试器,您可以逐行执行您的程序,并查看它偏离预期的地方。这是一个必要的工具,如果你要做任何编程。进一步阅读:不要介意最后的评论。我甚至没想过。感谢您的帮助指针只是一个8字节的数字,就像一个长整数。如果parent->left存储了一个节点的地址,并且您设置了另一个指针n=parent->left,那么节点的相同8字节内存地址存储在两个地方——一个在父节点的“left”字段中,另一个在临时变量n中。现在,如果您“delete n;”,则存储在变量n和parent->left中的值仍然是旧的(现在无效)地址,而不是nullptr。
if(!n->lChild && !n->rChild){ //n has no children
  delete n;
  n = nullptr;
}