您的位置:首页 > 理论基础 > 数据结构算法

严蔚敏数据结构中二叉排序树删除操作的问题(与链表比较)

2018-02-21 23:03 513 查看
        在严蔚敏的《数据结构》中,我看到二叉排序树中有几行代码,我理解的不是很清楚,如下,想请教大家,并且加深自己对指针这一块的理解,代码片段如下:Status Delete(BiTree& p)
{
//从二叉排序树中删除结点p,并重接它的左或右子树
if(! p->rchild) //右子树为空则只需重接它的左子树
{
q = p;
p = p->lchild;
free(q);
}
//剩余情况在此省略了...
}
        对于上面这三行代码,我有一点疑惑之处在于:我们虽然执行了p = p->lchild,但是依据链表知识的学习,假设p所指向的结点的父结点为f的话,不应该也改变f->lchild或者f->rchild吗?后来,我查到有人对这几行的解释是:q = p; //我们不妨设p是其父结点的rchild, 所以这行代码的意思就是:
//将父结点的->rchild空间中存放的待删除结点p的地址放入q中

p = p->lchild; //将待删除结点左孩子的地址放入父结点的->rchild空间中
free(q);
        我带着疑惑与少许的理解,把书中所给的伪代码修改成可以跑通的,我用45, 24, 53, 45, 12, 24, 50, 40这几个数做一个测试,正确的二叉排序树应该是这样:
                                                         


        我们以删除53为例,部分代码片段如下:int Delete (BiTree& T, BiNode*& p)
{
if (! p->lchild && ! p->rchild )
{
p = NULL;
delete p;
}
else //左右子树至少有一个不空
{
if ( ! p->lchild ) //左子树为空,右子树不空
{
}
else if ( ! p->rchild ) //右子树为空
{
BiNode* q = p;
p = p->lchild;
delete q;
}
else //左右子树都不空
{
}
}
return 0;
}
   在调试中,我发现在执行"p = p- >lchild"之前,45, 53, 50三个结点的地址如图所示:


而在执行了"p = p->lchild;    delete q;”这两句话之后,45的rchild的地址就变成了eec8也就是说45成功得按照我们的意愿指向了50,并且删除了53这个结点。那么我觉得可以理解为,45所代表的的这个结点的rchild域中原先存的是e918,在执行了"p = p->lchild"之后,原先存的e918被修改成了eec8。        带着对这部分的理解,我想起学过的链表删除某个元素的操作,假设我们要删出p结点之后的那个结点

//一般来说,会这样操作
ListNode* q = p->next;
p->next = q->next;
delete q;我觉得,按照在二叉排序树中删除53的那个操作,我做如下操作是可以的,代码片段如下,但是调试的结果是: p结点的next域中的地址并没有改变struct ListNode
{
int data;
ListNode* next;
};
typedef ListNode* List;
.....
ListNode* Locate (List& L, int data)
{
ListNode* p;
for ( p = L; p->next->data != data; p = p->next );
return p;
}
//删除结点p的后一个结点
int Delete (List& T, ListNode*& p)
{
ListNode* q = p->next;
q = q->next;
delete q;
return 0;
}
....

    我拿0~5这5个数作为测试,地址如下:



    (下面这段话中,都是以先不执行delete或者free为基础说的)
    以删除2这个结点为测试,按照"q = q->next"执行后,完全没有效果,只是q指针的地址变成了ecd8,p的next域中的地址还是eb18,也就是说没有删除q这个结点;相反的按照"p->next = q->next"来执行,就可以成功得更改p的next域中的地址为ecd8。
    总结问题:我是用C语言写的二叉排序树的删除,但是用了C++中的引用,我看还有其他方法是用二级指针的,我个人认为使用"引用/二级指针"是都可以的,所以问题应该没有出在这里。但是为什么同样"q = q->next"操作,在二叉排序树中,q的父结点的孩子域中的地址就改变了,但是在链表中q的父结点的next域中的地址却不变?

            

   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐