C 从树结构中删除项

C 从树结构中删除项,c,data-structures,struct,C,Data Structures,Struct,我有这个结构: typedef struct Tree { int arrel; struct Tree *dret; struct Tree *esq; unsigned int talla; } Tree; 采用以下方法: void crearArbre (struct Tree *arbre, int val_arrel) { arbre->arrel = val_arrel; arbre->dret = NULL; arbre->esq =

我有这个结构:

typedef struct Tree {
  int arrel;
  struct Tree *dret;
  struct Tree *esq;
  unsigned int talla;
} Tree;
采用以下方法:

void crearArbre (struct Tree *arbre, int val_arrel)
{
  arbre->arrel = val_arrel;
  arbre->dret = NULL;
  arbre->esq = NULL;
  arbre->talla = 0;
}
int inserir (struct Tree *arbre, int valor) //Insert method
{
  struct Tree *aux = arbre;
  struct Tree *ant = NULL;
  while (aux != NULL && aux->arrel - valor != 0)
    {
      ant = aux;
      if (aux->arrel > valor)
    {
      aux = aux->esq;
    }
      else
    aux = aux->dret;
    }
  if (aux == NULL)
    {
      if (ant->arrel > valor)
    {
      //ant -> esq -> arrel = valor;
      ant->esq = (struct Tree *) malloc (sizeof (struct Tree));
      ant->esq->arrel = valor;
      //crearArbre(ant -> esq ,valor);
    }
      else
    {
      ant->dret = (struct Tree *) malloc (sizeof (struct Tree));
      ant->dret->arrel = valor;
    }
    }
  arbre->talla += 1;
  return 0;

}
int rem (struct Tree *arbre, int valor) //Remove method
{
  if (arbre == NULL)
    return NULL;
  if (valor < arbre->arrel)
    {
      return rem (arbre->esq, valor);
    }
  else if (valor > arbre->arrel)
    {
      return rem (arbre->dret, valor);
    }
  else
    {
      int val = arbre->arrel;
      arbre = NULL; //Not sure about this
      free (arbre); //?
      return val;
    }
}
void printarArbre (struct Tree *arbre) //Post order printing method
{
  if (arbre != NULL)
    {
      printarArbre (arbre->esq);
      printarArbre (arbre->dret);
      printf ("%d -> ", arbre->arrel);
    } 

}
void crearararbre(结构树*arbre,内部值)
{
arbre->arrel=val_arrel;
arbre->dret=NULL;
arbre->esq=NULL;
arbre->talla=0;
}
int-inserir(结构树*arbre,int-valor)//插入方法
{
结构树*aux=arbre;
结构树*ant=NULL;
while(aux!=NULL&&aux->arrel-valor!=0)
{
ant=aux;
如果(辅助->arrel>valor)
{
aux=aux->esq;
}
其他的
aux=aux->dret;
}
如果(aux==NULL)
{
如果(ant->arrel>valor)
{
//ant->esq->arrel=勇气;
ant->esq=(结构树*)malloc(sizeof(结构树));
ant->esq->arrel=勇气;
//crearArbre(ant->esq,valor);
}
其他的
{
ant->dret=(结构树*)malloc(sizeof(结构树));
蚂蚁->德雷特->阿雷尔=勇气;
}
}
arbre->talla+=1;
返回0;
}
int-rem(结构树*arbre,int-valor)//删除方法
{
如果(arbre==NULL)
返回NULL;
如果(valorarrel)
{
返回rem(arbre->esq,valor);
}
否则如果(valor>arbre->arrel)
{
返回rem(arbre->dret,valor);
}
其他的
{
int val=arbre->arrel;
arbre=NULL;//对此不确定
免费(arbre);/?
返回val;
}
}
void printarbre(结构树*arbre)//订单后打印方法
{
如果(arbre!=NULL)
{
printarArbre(arbre->esq);
printarArbre(arbre->dret);
printf(“%d->”,arbre->arrel);
} 
}

我一直在测试这个结构,插入一些数字,找到它们,最后删除一些元素。但是,在我从树中移除一个元素并调用
free()
之后,如果我调用
printarbre()
,在先前移除的元素的位置,如果我设置(
arbre=NULL
)然后调用
free(arbre)
,为什么它仍然被打印?我是否需要一个标志来指示节点是否已被删除?

请参见注释。正确的方法是:

int rem (struct Tree **arbreIn, int valor) //Remove method
{
  struct Tree *arbre= *arbreIn; // shorthand
  if (arbre == NULL)
    return NULL;
  if (valor < arbre->arrel)
    {
      return rem (&(arbre->esq), valor);
    }
  else if (valor > arbre->arrel)
    {
      return rem (&(arbre->dret), valor);
    }
  else
    {
      int val = arbre->arrel;
      free (arbre);    // free the node
      *arbreIn = NULL; // set the parent's pointer (esq or dret) to null
      return val;
    }
}
int-rem(结构树**arbreIn,int-valor)//删除方法
{
结构树*arbre=*arbreIn;//速记
如果(arbre==NULL)
返回NULL;
如果(valorarrel)
{
返回rem(&(arbre->esq),valor;
}
否则如果(valor>arbre->arrel)
{
返回rem(&(arbre->dret),valor;
}
其他的
{
int val=arbre->arrel;
释放(arbre);//释放节点
*arbreIn=NULL;//将父级的指针(esq或dret)设置为NULL
返回val;
}
}

请参见注释。正确的方法是:

int rem (struct Tree **arbreIn, int valor) //Remove method
{
  struct Tree *arbre= *arbreIn; // shorthand
  if (arbre == NULL)
    return NULL;
  if (valor < arbre->arrel)
    {
      return rem (&(arbre->esq), valor);
    }
  else if (valor > arbre->arrel)
    {
      return rem (&(arbre->dret), valor);
    }
  else
    {
      int val = arbre->arrel;
      free (arbre);    // free the node
      *arbreIn = NULL; // set the parent's pointer (esq or dret) to null
      return val;
    }
}
int-rem(结构树**arbreIn,int-valor)//删除方法
{
结构树*arbre=*arbreIn;//速记
如果(arbre==NULL)
返回NULL;
如果(valorarrel)
{
返回rem(&(arbre->esq),valor;
}
否则如果(valor>arbre->arrel)
{
返回rem(&(arbre->dret),valor;
}
其他的
{
int val=arbre->arrel;
释放(arbre);//释放节点
*arbreIn=NULL;//将父级的指针(esq或dret)设置为NULL
返回val;
}
}

Ah…我看到:在
int-rem(struct Tree*arbre,
arbre
是一个值。如果将其设置为null,则只有本地值被设置为null,而不是调用方的
arbe
。我想在这里您可以找到答案:当然,将
arbre
设置为null,然后调用
free(arbre)
永远不会释放内存,因为free不知道要释放什么(它当然会收到一个空值)。@PaulOgilvie但是在方法中,arbre是一个引用,所以我可以将它设置为空。好的,首先我将删除语句arbre=null;啊……我看到了:
int-rem(struct Tree*arbre,
arbre
是一个值。如果将其设置为null,则只有本地值设置为null,而不是调用者的
arbe
。我想在这里您可以找到答案:当然,将
arbre
设置为null,然后调用
free(arbre)
将永远不会释放内存,因为free不知道释放什么(它当然会收到一个空值)。@PaulOgilvie但是在方法中,arbre是一个引用,所以我可以将它设置为空,对吗?好的,首先我将删除语句arbre=null;