当前位置: 首页 > 知识库问答 >
问题:

函数从二叉搜索树中删除具有给定值的节点

王骏
2023-03-14

我有一个名为TreeNode的结构,它有一个int键、左键、右键和父键。我正试图用DeleteNode函数从树中删除一个节点,但它不起作用。我应该用左边子树中的最大值替换DeleteNode函数中已删除的节点。我的移植和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
    }
}
}

共有1个答案

皇甫建木
2023-03-14

首先,您有三个案例需要处理:(直接从维基百科。当我学习数据结构时,这对我来说很好)

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

删除一个没有子节点(叶):只需从树中删除该节点。

由于最大值(node->right),您似乎试图实现按顺序后继选项。

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

情况1:只需在叶节点上调用delete即可。

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;
TreeNode *inOrderSuccessor = maximum(del->right);
del->val = inOrderSuccessor->val; //you could use transplant/swap here
deleteNode(inOrderSuccessor, inOrderSuccessor->val);
 类似资料:
  • 我的删除方法由4个if语句组成,用于处理二叉查找树中的4种不同类型的删除。不确定哪里错了,但当我检查它时,它没有删除任何节点。如果赞赏,任何帮助。提前感谢' 我怀疑问题在于我试图将节点删除替换为空 }

  • 我正在为二元搜索树组装函数,结果遇到了麻烦。我正在研究当需要从树中删除包含指定值的节点时可能遇到的每种情况。如果节点没有左右子节点,我不确定如何处理释放节点。函数必须返回节点。我是否备份、检查每个左、右子级,并在子级中删除该值?但是如果该值在根中,我是否会遇到类似的问题,即如何删除它?作为解释,程序使用一个void指针,然后在一个单独的函数compare()中强制转换类型val,该函数计算两个值并

  • 在二元搜索树的情况下,为什么我们不能简单地在一个节点有两个子节点的情况下,将一个节点的前一个节点替换为后一个节点?

  • 当删除具有两个子节点的节点时,如果指示使用标准的二叉搜索树节点删除算法,我们应该将其替换为右子树的最小节点还是左子树的最大节点?

  • 我在做作业,实现自己的二叉查找树。问题是,我们有自己的节点实现,它的父节点是不可直接访问的。 我一直在寻找答案,但我不想完全照搬解决方案,尽管如此,我似乎仍然没有得到正确的答案。我错过了一些元素没有被删除的情况。 你能帮帮我吗?我做错了什么? 这是删除方法: 节点使用通用接口 只有比较的方法。它看起来像这样 我在remove中使用了另一种方法,它设置节点的父节点的子节点,具体取决于它的左子节点还是

  • 我写了一个函数,如果给定的二叉树是二叉搜索树,则返回true,否则返回false。 我的功能对吗?