注册 登录
编程论坛 数据结构与算法

关于 树的问题

发布于 2010-06-05 09:03, 845 次点击
删除二cha树中,以data域为x的结点为根的子树
我用的递归算法,可是删除后,遍历显示删除成功,但会出现乱码,大家看看怎么回事;
代码:
#include <stdio.h>
#include <malloc.h>

typedef char ElemType;
typedef struct node
{
    ElemType data;
    struct node *lchild,*rchild;
}BiNode,*BiTree;

BiTree CreatBiTree()
{
    BiTree T;
    ElemType x;
    scanf("%c",&x);
    if(x=='#') T=NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiNode));
        T->data=x;
        T->lchild=CreatBiTree();
        T->rchild=CreatBiTree();
    }
    return T;
}

void FREE(BiTree T)
{
    if(T)
    {
        FREE(T->lchild);
        FREE(T->rchild);
        free(T);
    }
}

void Delete(BiTree T,ElemType x)
{
    if(T)
    {
        Delete(T->lchild,x);
        Delete(T->rchild,x);
        if(T->data==x)
        {
            FREE(T);
            T=NULL;
        }
    }
}

void preorder(BiTree T)
{
    if(T)
    {
        printf("%c",T->data);
        preorder(T->lchild);
        preorder(T->rchild);
    }
}

void inorder(BiTree T)
{
    if(T)
    {
        inorder(T->lchild);
        printf("%c",T->data);
        inorder(T->rchild);
    }
}

int main()
{
    BiTree T;
    ElemType x;
    T=CreatBiTree();
    preorder(T);
    printf("\n");
    inorder(T);
    printf("\n");
    getchar();
    scanf("%c",&x);
    Delete(T,x);
    preorder(T);
    printf("\n");
    inorder(T);
    printf("\n");
    return 0;
}
比如:abdh###e#i##cfj###g##
删除c
输出:
abdhei&*^
hdbeia&*^
后面的&*^表示乱码,共三位,每次释放空間的时候,我都设为空了啊,怎么还会出现乱码呢?
8 回复
#2
hzh5122010-06-05 09:34
你在delete中确实把结点给删掉了,可是别忘了结点a(根)还在指着他呢,你应该把结点a的右子树置为NULL。 不应该 观前不顾后
#3
2010-06-05 09:58
void Delete(BiTree T,ElemType x)
{
    if(T)
    {
        Delete(T->lchild,x);
        Delete(T->rchild,x);
        if(T->data==x)
        {
            FREE(T);
            T=NULL;
        }
    }
}


我在删除c时,已经将结点设为NULL了 啊,好像问题不在这儿.
#4
hzh5122010-06-05 10:16
非要让我亲自动手,好吧
换成我这个就可以了
void Delete(BiTree &T,ElemType x)
{
    if(T)
    {
        Delete(T->lchild,x);
        Delete(T->rchild,x);
        if(T->data==x)
        {
            FREE(T);
            T=NULL;
        }
    }
}
#5
hzh5122010-06-05 10:28
或者你不用C++,也就不能用引用。此时你可以用二级指针来代替
别忘了在main函数中,加上 &
程序代码:
void Delete(BiTree *T,ElemType x)
{
    if(*T)
    {
        Delete(&(*T)->lchild,x);
        Delete(&(*T)->rchild,x);
        if((*T)->data==x)
        {
            FREE(*T);
            *T=NULL;
        }
    }
}


#6
2010-06-05 16:29
为什么要用二级指针呢?我还是不懂您的意思,问题真的在这儿吗?
#7
hzh5122010-06-05 18:08
你自己换上试一试不就知道了吗。难道你编程从不调试,你完全可以设个断点,自己看看 a的右子树是否为NULL,你的程序肯定不是NULL。

你认为设成NULL,其实你没改,你改的是T这个局部变量。而且,我记得以前说过函数调用会产生临时对象(这里的函数参数就是)。
另外,还告诫过你,不要直接传对象,要传引用(当然也可以是指针)。
值传递和地址传递,你应该明白吧!在这里使用二级指针,是因为你要修改的是一个地址,所以要用指向地址的指针。



#8
2010-06-05 22:32
我发现,我真不明白,得重新学学这.........见笑了..
#9
傻傻丫头2010-06-08 23:24
去年才学的忘的差不多了
1