Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/95.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,我有一个名为TreeNode的结构,带有一个int键,左键和右键以及父键。我正在尝试使用DeleteNode函数从树中删除节点,但它不起作用。我应该用左子树中的最大值替换DeleteNode函数中已删除的节点。My transplant和max函数是DeleteNode的助手函数。我的问题是我不确定在DeleteNode函数中我应该在哪里比较我所在的节点值和我通过函数传递的值。我的代码中有一条带有星号的注释,我不知道该怎么做。任何帮助都将不胜感激 void transplant(TreeNode

我有一个名为TreeNode的结构,带有一个int键,左键和右键以及父键。我正在尝试使用DeleteNode函数从树中删除节点,但它不起作用。我应该用左子树中的最大值替换DeleteNode函数中已删除的节点。My transplant和max函数是DeleteNode的助手函数。我的问题是我不确定在DeleteNode函数中我应该在哪里比较我所在的节点值和我通过函数传递的值。我的代码中有一条带有星号的注释,我不知道该怎么做。任何帮助都将不胜感激

void transplant(TreeNode* u, TreeNode* v)   //swaps u with v
{

if (u->parent == NULL)  //if u was root, make v new root
    u->parent = v;
else if (u == u->parent->left)  //if u is smaller than it's parent
    u->parent->left = v;        //set v to the left child of parent of u. Swap them at left, really
else
    u->parent->right = v;       //otherwise swap them at right

if (v != NULL)              //reassign parents to double link
    v->parent = u->parent;
}

TreeNode* maximum(TreeNode* n)
{

while (n->left != NULL)
    n = n->left;
return n;
}

  void deleteNode(TreeNode *node, int key)
{

if (node->left == NULL)                 //if there is no left child
    transplant(node, node->right);      //swap 
else if (node->right == NULL)           //if there is no right child
    transplant(node, node->left);       //swap 
else 
{
  if(node->key == key){ //****This if comparison must be wrong***
    TreeNode* temp = maximum(node->right);  //make temp the max on right
    if (temp->parent != node )              //if it is more than one chain down
    {
        transplant(temp, temp->right);          //swap temp and it's right branch
        temp->right = node->right;          //set right branch to nodes right
        temp->parent->right = temp;             //set temp to the right child 
    }
    transplant(node, temp);                 // transplant
    temp->left = node->left;                //get nodes left branch
    temp->left->parent = temp;              //replace
    }
}
}

首先,你需要处理三个案例:(直接来自维基百科。当我学习数据结构时,这对我来说非常棒)

有三种可能的情况需要考虑:

删除没有子节点(叶)的节点:只需从树中删除节点

删除具有一个子节点的节点:删除该节点并将其替换为其子节点

删除具有两个子节点的节点:调用要删除的节点N。不要删除N。而是选择其顺序后续节点或顺序前置节点R。将R的值复制到N,然后递归调用R上的delete,直到达到前两种情况之一

广义上讲,具有子节点的节点更难删除。与所有二叉树一样,节点的有序后继树是其右子树最左边的子树,节点的有序前继树是左子树最右边的子树。在任何一种情况下,此节点都将有零个子节点或一个子节点。根据上面两个简单的情况之一删除它

由于最大值(节点->右侧),您似乎正在尝试实现顺序后续选项

现在我们已经确定了你可能的病例,唯一真正需要移植的病例是第三例,我认为有两个孩子

案例1:只需在叶节点上调用delete

案例2:

这里,del是要删除的节点(在本例中,del有一个正确的子节点)。我很快就写了这个。第一个if语句检查del是否是其父节点的左子节点,然后通过将其父节点指向其子节点,将其自身从指针表达式中“移除”,反之亦然。第二个if执行相同的操作,但检查del是否是其父节点的正确子节点。最后,删除节点

del->right->parent = del->parent;
if (del == del->parent->left)
    del->parent->left = del->right;
else if (del == del->parent->right)
    del->parent->right = del->right;
delete del;
案例3:

TreeNode *inOrderSuccessor = maximum(del->right);
del->val = inOrderSuccessor->val; //you could use transplant/swap here
deleteNode(inOrderSuccessor, inOrderSuccessor->val);

就这样。

您是否已经使用调试器逐行检查代码了?