C++:删除BST中的一个节点,要么得到一个seg错误,要么重复节点

C++: Deleting a node in BST, either gets a seg fault or duplicates node

本文关键字:节点 一个 seg 错误 C++ BST 删除      更新时间:2023-10-16

所以我做了很多搜索,但许多有删除问题的人都有与我完全不同的BST实现。在这次任务中,我们得到了一个BST类,该类具有字段nodeContent,以及指向root、leftChild和rightChild的指针。本周的任务是创建一个函数,删除树中的指定节点,然后我们应该能够遍历树来验证节点是否已经消失。我认为我的过程很好,但当我测试代码时,它要么返回节点确实已被删除,要么返回我从中复制的节点已被复制。或者,当我试图删除有两个孩子的笔记时,我会遇到分段错误。我刚开始在SO上发帖,所以如果我做得不对,我道歉。我一直在绞尽脑汁,想知道我哪里错了!提前谢谢。哦,是的,我为这么多评论道歉。。当我陷入困境时,我会添加很多评论,试图通过这些步骤与自己交谈。

            /*
            void BST::deleteNode(int el)
            Input: An integer that is to be deleted from the tree
            Output: Nothing
            Side Effect: Single node deleted and tree reordered
            */
            void BST::deleteNode(int el)
            {
              BSTNode *temp;
              BSTNode *prev;
              BSTNode *node = Root;
              while (node -> nodeContent != el && node != NULL) // start the search
              {
                // if the search is less than 
                if(el < node -> nodeContent)
                {
                  node = node -> leftChild;
                }
                else if (el > node -> nodeContent)
                {
                  node = node -> rightChild;
                }
                if (node == NULL)
                {
                  std::cout << "That item cannot be deleted, "
                              "because it doesn't exist" << std::endl;
                  return;
                }
              }
              // ok, so we found the node
              // this is if node has two children
              if (node -> leftChild != NULL && node -> rightChild != NULL)
              {
                // first, set temp to rightmost node in left subtree
                temp = node -> leftChild;
                while (temp -> rightChild != NULL)
                {
                  // set prev to the node above node (bad name resolution, I know..)
                  prev = temp;
                  temp = temp -> rightChild;
                }
                // now we have our node, temp, and prev set.
                // time to do some copying
                // first step: set prev's rightChild to NULL
                prev -> rightChild = NULL;
                // ok. now we need to check if temp has a left child
                if (temp -> leftChild != NULL)
                {
                  //if it does, set it to prev's rightChild
                  prev -> rightChild = temp -> leftChild;
                }
                // done. Now set nodes content to temps content
                node -> nodeContent = temp -> nodeContent;
                // good work. now delete temp
                delete temp;
                temp = NULL;
              }
              // this one is for deleting a node without a right child
              if (node -> rightChild == NULL && node -> leftChild != NULL)
              {
                // using temp this time as the leftChild of the node to be deleted
                temp = node -> leftChild;
                // copy the content from child to node's content
                node -> nodeContent = temp -> nodeContent;
                // george r.r. martin the heck out of temp, for his watch has ended
                delete temp;
                temp = NULL;
              }
              // now, if (soon-to-be) deleted node only has a right child
              if (node -> leftChild == NULL && node -> rightChild != NULL)
              {
                // set temp to be nodes rightChild
                temp = node -> rightChild;
                // copy content from temp to to node
                node -> nodeContent = temp -> nodeContent;
                // delete temp
                delete temp;
                temp = NULL;
              }
              // the last one should be the easiest, if the node has no children
              if (node -> leftChild == NULL && node -> rightChild == NULL)
              {
                delete node;
              } 
            }

您使用了三个if语句,并且没有从任何块返回。因此,假设您的第一个if语句得到满足,并且该节点只有一个合适的子节点。此孩子已被删除。

现在,代码转到第二个if语句,这反过来也是真的!然后它执行第二个CCD_ 4块。

我希望这能让你找到答案。此外,为了找到分段故障发生的确切位置GDB。如果您使用C++进行编码,它是一个必不可少的工具。

相关文章: