问题在于最后的删除步骤(在最后的else语句中)以及如何重新分配父节点对子节点的引用。代码来自Mark Allen Weiss的《C++中的数据结构和算法分析》一书。整个代码的引用:https://users.cis.fiu.edu/~weiss/dsaa_c++3/code/binarysearchtree.h
根据我对程序的理解,节点指针t指向要删除的节点。
然后将该指针复制到节点指针oldNode,然后t指向子节点(如果有)(在本例中,由于findMin是右子节点)。
然后删除oldNode指向的节点。
但是如何将父节点指针(oldNode指向的节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父节点的父
方法如下:
void remove( const Comparable & x, BinaryNode * & t )
{
if( t == NULL )
return; // Item not found; do nothing
if( x < t->element )
remove( x, t->left );
else if( t->element < x )
remove( x, t->right );
else if( t->left != NULL && t->right != NULL ) // Two children
{
t->element = findMin( t->right )->element;
remove( t->element, t->right );
}
else
{
BinaryNode *oldNode = t;
t = ( t->left != NULL ) ? t->left : t->right;
delete oldNode;
}
}
//findMin method used in the above routine
BinaryNode * findMin( BinaryNode *t ) const
{
if( t == NULL )
return NULL;
if( t->left == NULL )
return t;
return findMin( t->left );
}
在remove
函数的签名中,binarynode*&t
是对binarynode
类型指针的引用。也就是说,它是对父节点的左/右节点指针的引用。
我为你做了一个简单的图表,因为“一图胜过千言万语”。
因此,基本上,它首先将引用所引用的实际指针(橙色箭头)保存到oldnode
中,然后将被引用的变量(红点)设置为指向下一个子节点的指针(绿色箭头),跳过oldnode
,最后删除oldnode
。
我正在制作一个按字符串键排序的二叉搜索树。每个节点由一个与一个键相关联的无序信息链表组成。这棵树是按字母顺序排列的。 我已经完成了大部分的程序,但有麻烦的删除方法。 谢谢你。
当删除具有两个子节点的节点时,如果指示使用标准的二叉搜索树节点删除算法,我们应该将其替换为右子树的最小节点还是左子树的最大节点?
我正在尝试为我一直在研究的BST结构实现一个移除方法。以下是包含查找、插入和删除方法的代码: 我被告知可以使用insert方法来帮助我使用remove方法,但我只是不知道如何获取最小/最大的元素,然后用该值替换我正在删除的元素,然后递归地删除我获取替换值的节点,同时仍然保持O(logn)的复杂性。有人有什么想法或明显的漏洞我错过了,或任何其他有帮助的,因为我撞我的头在这个问题上? 编辑:我用答案的
我正在阅读一本书,该书解释了如何从二元搜索树中删除节点,基本上如果我们有这棵树: 我们想删除节点4,书上说我应该: 在其右子树(即6)中找到4的继任者 交换4和6 从右子树中删除6 将4的左侧子树(在本例中仅为1)附加到新节点6 因此我们得到 然而,我想到了另一种方法来做到这一点: 找到4个右子树的最小元素(即6) 将4的左子树附加到6(它不会有左子树) 将父元素(10)附加到4的右侧元素(8)。
我的删除方法由4个if语句组成,用于处理二叉查找树中的4种不同类型的删除。不确定哪里错了,但当我检查它时,它没有删除任何节点。如果赞赏,任何帮助。提前感谢' 我怀疑问题在于我试图将节点删除替换为空 }
这里是我试图实现的BST,但是remove方法不会删除具有给定值的节点。我试着这样做: 首先检查当前节点(我要删除的节点)是否有正确的子节点。 1.2.1)如果右子节点有一个左子节点,则我将当前节点替换为最小节点,该最小节点大于当前节点,并替换为右子树中最左侧的节点 1.2.2)如果没有,我就用它的正确子节点替换当前节点,但是代码没有删除选中的节点,哪里出错了?