免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1322 | 回复: 8
打印 上一主题 下一主题

[算法] 算法求助! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-04-13 19:33 |只看该作者 |倒序浏览
请大家看看,下面这个 删除 二叉树结点的算法错在哪里,我挺急,请各位指教,谢谢

void delnote(bstree *bt,bstree p,bstree q)   // q 是p的父结点,p是要  删结点
{
        bstree s,r;

        if(p->;lchild == NULL)                          //左子树为空
        {
                 if(p == *bt)
                        *bt = p->;rchild;
                        
                else if (q->;lchild == p )
                          q->;lchild = p->;rchild;
                else
                        q->;rchild = p->;rchild;

        }

        else if (p->;rchild == NULL)                //右子树为空
        {
                if(p == *bt)
                        *bt = p->;lchild;

                else if(q->;lchild == p)
                         q->;lchild = p->;lchild;

                else
                         q->;rchild = p->;lchild;

        }
        else                                     <-----  因该是这里错了
        {
               s = p;
               r = s->;rchild;
               while(r->;lchild != NULL)   //找最左结点 *r,*s是 *r的父结点
                {
                        s =r;
                        r = r->;lchild;
                }
                r->;lchild = p->;lchild;
                if(p!=s)
                {
                        r->;lchild = p->;lchild;
                        r->;rchild = p->;rchild;
                }
                if(p == *bt)
                         *bt = r;

                else if(q->;lchild== p)                  //删除的是q的左孩子
                        q->;lchild =r;

                else
                        q->;rchild = r;                      //删除的是q的右孩子
        }
                free(p);
}

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2003-04-14 09:40 |只看该作者

算法求助!

else {
s = p;
r = s->;rchild;
while(r->;lchild != NULL) //找最左结点 *r,*s是 *r的父结点
{
在什么条件下执行呢?

论坛徽章:
0
3 [报告]
发表于 2003-04-14 10:16 |只看该作者

算法求助!

是不是如果p有左右孩子,那么把右孩子赋给p的最左孩子的右孩子?

如果是
if(p!=s)
{
r->;lchild = p->;lchild;
r->;rchild = p->;rchild;
}
改为:
if(p!=s)
{
r->;rchild = p->;rchild;
}
即可!

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
4 [报告]
发表于 2003-04-14 12:50 |只看该作者

算法求助!

void delnote(bstree *bt,bstree p,bstree q) // q 是p的父结点,p是要 删结点
{
bstree s,r;

if(p->;lchild == NULL) //左子树为空
{
if(p == *bt) //不是用形参给出p的父接点了吗?怎么还要判断?思路不清晰。
*bt = p->;rchild;
                 
else if (q->;lchild == p )
q->;lchild = p->;rchild;
else
q->;rchild = p->;rchild;

}

else if (p->;rchild == NULL) //右子树为空
{
if(p == *bt)
*bt = p->;lchild;

else if(q->;lchild == p)
q->;lchild = p->;lchild;

else
q->;rchild = p->;lchild;

}
else <----- 因该是这里错了
{
        s = p;
        r = s->;rchild;
        while(r->;lchild != NULL) //找最左结点 *r,*s是 *r的父结点
        {
                s =r;
                r = r->;lchild;
        }
        r->;lchild = p->;lchild;
        if(p!=s)
        {
                r->;lchild = p->;lchild; //同上面的语句重复。
                r->;rchild = p->;rchild;
        }
        if(p == *bt)
                *bt = r;  //此处应该删除原先r的父接点指向r的指针。否则会多出这样一条线。

        else if(q->;lchild== p) //删除的是q的左孩子
                q->;lchild =r;  //这里p的右子树怎么办?被整个砍下去了。

        else
                q->;rchild = r; //删除的是q的右孩子
                               //同样,p的左子树呢?
}
free(p);
}

问题写在上面的注释里了。
应该去找本数据结构的书好好看看。p删除后,p的左右子树不同的安排方法应该有不同的删除方法。
还有,写程序应该有一定的缩进,有层次感以增加程序的可读性。
前面,p只有一个子树的时候,删除写得不错。p有两个子树的时候就糊涂了,在“画图”里画一画就明白了。

论坛徽章:
0
5 [报告]
发表于 2003-04-14 13:17 |只看该作者

算法求助!

谢谢大家的回复,现将函数修改如下
。。。

else
        {
                s = p;
                r = s->;rchild;

                while(r->;lchild != NULL)
                {
                        s =r;
                        r = r->;lchild;
                }
                r->;lchild = p->;lchild;
                if(p!=s)
                {
                        r->;rchild = p->;rchild;
                        s->;lchild = NULL;             //删掉r的父结点指针
                }
                if(p == *bt)
                         *bt = r;

                else if(q->;lchild== p)              //父结点的右子树没砍呀,照旧
                        q->;lchild =r;

                else                                        //此同上
                        q->;rchild = r;
        }

。。。

论坛徽章:
0
6 [报告]
发表于 2003-04-14 13:18 |只看该作者

算法求助!

谢谢大家的回复,现将函数修改如下
。。。

else
        {
                s = p;
                r = s->;rchild;

                while(r->;lchild != NULL)
                {
                        s =r;
                        r = r->;lchild;
                }
                r->;lchild = p->;lchild;
                if(p!=s)
                {
                        r->;rchild = p->;rchild;
                        s->;lchild = NULL;             //删掉r的父结点指针
                }
                if(p == *bt)
                         *bt = r;

                else if(q->;lchild== p)              //父结点的右子树没砍呀,照旧
                        q->;lchild =r;

                else                                        //此同上
                        q->;rchild = r;
        }

。。。

论坛徽章:
0
7 [报告]
发表于 2003-04-14 13:22 |只看该作者

算法求助!

算法太难了!

论坛徽章:
0
8 [报告]
发表于 2003-04-14 14:02 |只看该作者

算法求助!

呵呵,上面修改的算法还是不对
再修改为以下

。。。。

else
        {
                s = p;
                r = s->;rchild;

                while(r->;lchild != NULL)
                {
                        s =r;
                        r = r->;lchild;
                }
                r->;lchild = p->;lchild;
                if(p!=s)
                {
                        s->;lchild = r->;rchild;   //**此应该将r的右子树做 r 的父结点的左子树
                        r->;rchild = p->;rchild;
                }
                if(p == *bt)
                        *bt = r;

                else if(q->;lchild== p)
                         q->;lchild =r;

                else
                         q->;rchild = r;}
        }


。。。。。

论坛徽章:
0
9 [报告]
发表于 2003-04-14 18:27 |只看该作者

算法求助!

函数是该这样void delnote(bstree *bt,bstree p,bstree q),还是该这样
void delnote(bstree *bt,bstree *p,bstree *q)

还有你的目的是什么?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP