实现二叉树时双重自由或损坏

时间:2014-05-29 23:48:04

标签: c++ binary-tree

更新

在问题结尾处添加更多代码。谢谢所有停下来的人。

当前代码可以删除一个叶子,但是来到Root,它无法删除。

==== 更新: 我修改代码,将removeRootMatch更改为

tmp = Root;
Root = tmp->Right; 
tmp->Right = NULL;
delete tmp;

并且没有错误,但它不会删除节点。

=====

程序很简单,请执行以下步骤:

  • 找到二叉树的最小值;
  • 在矢量中记录最小值;
  • 删除树中具有最小值的节点;
  • 重复1-3,直到树空了。

我有removeNode()函数,它将调用removeRoot函数(检查下面的代码),如果需要删除的是Root。但是这个功能有问题。我正在做一些调试,发现removeRootMatch函数有问题。它在运行时出错。我得到的错误是我得到的错误是*** glibc detected *** ./bintree: double free or corruption (fasttop): 0x0000000000727060 ***,任何人都可以帮助我吗?

树定义如下,语言为c ++

typedef struct myNode* LPNode;
typedef struct myNode Node;
struct myNode
{
  double key;

  LPNode Left; //left subtree
  LPNode Right; //right subtree
};

程序的主要部分如下:

  • nmax初始化为0,
  • sortedvector是一个向量,它的空间与树中的总节点一样大,
  • min的初始值为99999.
  • minValue将返回树的最小值。
  • compareDouble(a,b)将返回1 if a < b,返回2 if a > b,如果相等则返回3

代码如下

    void removeRootMatch(LPNode Root)
{
    LPNode tmp = MakeNewNode(Root->key);
    tmp->Left = Root->Left;
    tmp->Right = Root->Right;
    //no child
    if(Root->Left==NULL && Root->Right == NULL) {

        Root=NULL;
    delete Root;
    } else if(Root->Left==NULL && Root->Right!=NULL){ //one right child
        //delete Root;
            Root = tmp->Right;
        tmp->Right = NULL;
        delete tmp;
    } else {
        printf("Remove root bug!\n");
    }
}

这是函数调用removeNode函数。

//compare double
int compareDouble(double a,double b)
{
    if(a-b<-EPSILON) //a<b
        return 1;
    else if(a-b>EPSILON)//a>b
        return 2;
    else
        return 3;
}


//find the min key in a tree
double minValue(LPNode Root,double min) 
{
    if(Root == NULL)
        return min;
    if(compareDouble(Root->key,min)==1)
        min = Root->key;
    min = minValue(Root->Left, min);
    min = minValue(Root->Right, min);
    return min;
}

//remove root
void removeRootMatch(LPNode& Root)
{
    LPNode tmp = MakeNewNode(Root->key);
    tmp->Left = Root->Left;
    tmp->Right = Root->Right;
    //no child
    if(Root->Left==NULL && Root->Right == NULL) {
        Root=NULL;
        delete Root;
    } else if(Root->Left==NULL && Root->Right!=NULL){ //one right child

        double k = Root->key;


        Root = tmp->Right;
        tmp->Right = NULL;
        delete tmp;
        //tmp=tmp->Right;
        //Root->Right = NULL;
        //delete Root;
        //Root = tmp;





    } else {
        printf("Remove root bug!\n");
    }
}

//remove a node
void removeMatch(LPNode& Root,LPNode match,bool left)
{
    //no child
    if(match->Left==NULL && match->Right == NULL){
        double k = match->key;
        left==true?
        Root->Left=NULL:
        Root->Right=NULL;
        delete match;
        if(!Root->Left)printf("%f  ",k);
    }
    else if(match->Left==NULL && match->Right!=NULL){//one right child
                double k = match->key;

        left==true?
        Root->Left=match->Right:
        Root->Right=match->Right;
        delete match;
        if(!Root->Left)printf("%f  ",k);
    } else {
        printf("Remove root bug!\n");
    }
}


//delete a node
void removeNode(LPNode Root,double min)
{
    if(compareDouble(min,Root->key)==3){
        removeRootMatch(Root);
    }else if(compareDouble(min,Root->key)==1 && Root->Left != NULL) {

        compareDouble(min,Root->Left->key)==3 ?
        removeMatch(Root,Root->Left,true):
        removeNode(Root->Left,min);
    }else if(compareDouble(min,Root->key)==2 && Root->Right != NULL){

        compareDouble(min,Root->Right->key)==3 ?
        removeMatch(Root,Root->Right,false):
        removeNode(Root->Right,min);
    }else{
        printf("Remove bug1!\n");
    }
}

//call minValue to find the min key
//record the min key in a vector
//call removeNode to delete the Node
//repeat till the tree is empty
void problem1(LPNode Root,double* sortedvector,int& nmax)
{       
    double min;
    //while(Root!=NULL)
    for(int i=0;i<3;i++)
    {
        min = MAX;
        sortedvector[nmax] = minValue(Root,min) ;
        printf("inv%f\n",sortedvector[nmax]);
        removeNode(Root,sortedvector[nmax]);
        nmax++;
    }
    printf("The tree is empty");
}

1 个答案:

答案 0 :(得分:1)

如果你的函数removeNode可以调整Root,那么你的函数没有被正确声明。

 void removeRootMatch(LPNode Root)

您正在将指针传递给Root。在removeRootMatch函数内部,您正在处理指针的副本。所以removeRootMatch函数中的代码就是这样的代码:

Root = tmp->Right;
    tmp->Right = NULL;
    delete tmp;
函数返回时

不会更改Root节点。

要解决此问题,您应该通过引用传递Root指针:

 void removeRootMatch(LPNode& Root)