Trying to limit a list in C - c

right now i'm trying to build a simple program as my homework for college, this was supposed to be a simple code but i'm learning c just now and i'm having a really bad time trying to learn it, anyways, this code should be able to add to add, remove, show and clear some numbers on the console, a list(i dont know if it's called that way in english), but 1 thing that i can't do and i have been researching and tryed to figure out is in how to put a limit on this list, exactly 20 numbers.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int num;
struct node *prox;
};
typedef struct node Fila;
int t;
int menu(void);
void opcao(Fila *f, int op);
void inicia(Fila *f);
int vazia(Fila *f);
Fila *aloca();
void insere(Fila *f);
Fila *retira(Fila *f);
void exibe(Fila *f);
void libera(Fila *f);
void liberar_mem(Fila *f);
int main(void)
{
Fila *f = (Fila *)malloc(sizeof(Fila));
if (!f)
{
printf("Sem memoria disponivel!\n");
exit(1);
}
else
{
inicia(f);
int opt;
do
{
opt = menu();
opcao(f, opt);
} while (opt);
free(f);
return 0;
}
}
int menu(void)
{
int opt;
printf("Escolha a opcao\n");
printf("0. Sair\n");
printf("1. Zerar solicitacoes\n");
printf("2. Exibir solicitacoes\n");
printf("3. Inserir o numero da solicitacao\n");
printf("4. Remover solicitacao\n");
printf("Opcao: ");
scanf("%d", &opt);
return opt;
}
void opcao(Fila *f, int op)
{
Fila *tmp;
switch (op)
{
case 0:
liberar_mem(f);
break;
case 1:
libera(f);
inicia(f);
break;
case 2:
exibe(f);
break;
case 3:
insere(f);
break;
case 4:
tmp = retira(f);
if (tmp != NULL)
{
printf("Solicitacao removida: %3d\n\n", tmp->num);
free(tmp);
}
break;
default:
printf("Comando invalido\n\n");
}
}
void inicia(Fila *f)
{
f->prox = NULL;
t = 0;
}
int vazia(Fila *f)
{
if (f->prox == NULL)
return 1;
else
return 0;
}
Fila *aloca()
{
Fila *novo = (Fila *)malloc(sizeof(Fila));
if (!novo)
{
printf("Sem memoria disponivel!\n");
exit(1);
}
else
{
printf("Insira o numero da solicitacao: ");
scanf("%d", &novo->num);
return novo;
}
}
void insere(Fila *f)
{
Fila *novo = aloca();
novo->prox = NULL;
if (vazia(f))
f->prox = novo;
else
{
Fila *tmp = f->prox;
while (tmp->prox != NULL)
tmp = tmp->prox;
tmp->prox = novo;
}
t++;
}
Fila *retira(Fila *f)
{
if (f->prox == NULL)
{
printf("Lista de solicitacoes ja esta vazia\n");
return NULL;
}
else
{
Fila *tmp = f->prox;
f->prox = tmp->prox;
t--;
return tmp;
}
}
void libera(Fila *f)
{
if (f->prox == NULL)
{
printf("Lista de solicitacoes ja esta vazia\n");
Fila *proxNode, *atual;
atual = f->prox;
while (atual != NULL)
{
proxNode = atual->prox;
free(atual);
atual = proxNode;
}
}
else
{
if (!vazia(f))
{
Fila *proxNode, *atual;
atual = f->prox;
while (atual != NULL)
{
proxNode = atual->prox;
free(atual);
atual = proxNode;
}
}
}
}
void exibe(Fila *f)
{
if (vazia(f))
{
printf("Nenhuma solicitacao cadastrada!\n\n");
return;
}
Fila *tmp;
tmp = f->prox;
printf("Fila :");
while (tmp != NULL)
{
printf("%5d", tmp->num);
tmp = tmp->prox;
}
printf("\n ");
int count;
for (count = 0; count < t; count++)
printf(" ^ ");
printf("\nOrdem:");
for (count = 0; count < t; count++)
printf("%5d", count + 1);
printf("\n\n");
}
void liberar_mem(Fila *FILA)
{
if (!vazia(FILA))
{
Fila *proxNode, *atual;
atual = FILA->prox;
while (atual != NULL)
{
proxNode = atual->prox;
free(atual);
atual = proxNode;
}
}
}

You could use a global variable that keeps track of the current length of the list and return an error message when someone tries to expand the list beyond the limit.
However, while global variables are fine for simple programs, it's considered good style for larger programs to rely upon them as little as possible.
Therefore, I'd recommend using a "list header" object. For example,
#define MAX_LIST_LENGTH 20
struct list_header {
Fila *start_of_list;
unsigned int current_length;
};

Related

Binary Search Tree, recursive function Exsists throw "core dumped" in comparation strings

I have the following the following structures to define an Binary Search Tree:
typedef struct Equipo {
char nombre[50];
char marcaMoto[30];
int puntuaciones;
struct Piloto pilotos[18];
struct nodo* izquierdo;
struct nodo* derecho;
} Equipo;
typedef Equipo Arbol;
the search in the tree will be performed by the string nombre, a char [50]. For create tree and insert data I use the functions:
Equipo* CrearEquipo(Equipo* e) {
Equipo* n = (Equipo *) malloc(sizeof(Equipo));
strncpy(n->nombre, e->nombre, 50);
strncpy(n->marcaMoto, e->marcaMoto, 30);
n->puntuaciones = 0;
n->derecho = n->izquierdo = NULL;
return n;
}
void InsertarEquipo(Equipo** arbol, Equipo* e) {
if (*arbol == NULL) {
Equipo* n = CrearEquipo(e);
*arbol = n;
} else {
int comparado = strncmp(e->nombre, (*arbol)->nombre, 50);
if (comparado > 0) {
InsertarEquipo(&(*arbol)->izquierdo, e);
} else {
InsertarEquipo(&(*arbol)->derecho, e);
}
}
}
And in main i use this functions to create test elements:
Equipo* equipo = (Equipo *) malloc(sizeof(Equipo));
strcpy(equipo->nombre, "C");
strcpy(equipo->marcaMoto, "B");
Arbol *arbol = CrearEquipo(equipo);
strcpy(equipo->nombre, "B");
strcpy(equipo->marcaMoto, "B");
InsertarEquipo(&arbol, equipo);
strcpy(equipo->nombre, "A");
strcpy(equipo->marcaMoto, "B");
InsertarEquipo(&arbol, equipo);
strcpy(equipo->nombre, "E");
strcpy(equipo->marcaMoto, "B");
InsertarEquipo(&arbol, equipo);
Later, I create the recursive function for comprobate if exists in the tree:
int ExisteEquipo(Equipo* arbol, char nombre[]) {
int comparado = strncmp(arbol->nombre, nombre, 50);
if (!arbol) {
return 0;
} else if (comparado > 0) {
printf("Menor ");
return ExisteEquipo(arbol->izquierdo, nombre);
} else if (comparado < 0) {
printf("Mayor ");
return ExisteEquipo(arbol->derecho, nombre);
} else {
printf("Igual ");
return 1;
}
}
(The printf's are for test). When I call the exists function with:
void DeterminarExistencia(Equipo* arbol, char nombre[50]) {
if (ExisteEquipo(arbol, nombre)) {
printf("El nodo %s existe. \n", nombre);
} else {
printf("El nodo %s no existe. \n", nombre);
}
}
DeterminarExistencia(arbol, "E");
DeterminarExistencia(arbol, "C");
DeterminarExistencia(arbol, "H");
DeterminarExistencia(arbol, "B");
but I always get the error: Violación de segmento (core dumped) [Núcleo vaciado a un archivo]
I think the problem is here:
int comparado = strncmp(arbol->nombre, nombre, 50);
You are asking if arbol is null after operating with it with the line above, so if it is null you are accessing a wrong memory address and that is causing the error.
Put it like this:
if (!arbol) {
return 0;
int comparado = strncmp(arbol->nombre, nombre, 50);
Spanish:
Básicamente cambia el orden de lo que te he dicho arriba y deberia funcionar.

SearchDelete(ProcuraArvoreApaga) function breakpoint

I have a problem on the function ProcuraArvoreApaga which is a TreeSearchDelete function. I can't delete anything and when I try to delete the root it gives me a breakpoint.
When I try to delete the root I get the folowing breakpoint:
Exception thrown: read access violation.
raiz was 0xCCCCCCCC.
Here is the full code if you want to try by yourself or help me.
I use Visual Studio 2015
#include<stdio.h>
#include<stdlib.h>
#include<locale.h>
typedef struct tree *Arvore;
struct tree {
Arvore left;
Arvore right;
int *valor;
};
void DestruirNode(Arvore *raiz);
void ProcuraArvoreApaga(Arvore *raiz, int *value);
Arvore CriarArvore(int value) {
Arvore node;
if ((node = (Arvore)malloc(sizeof(struct tree))) == NULL) {
return NULL;
}
if ((node->valor = (int*)malloc(sizeof(int))) == NULL) {
return NULL;
}
*node->valor = value;
node->left = NULL;
node->right = NULL;
return node;
}
void DestruirArvore(Arvore *node) {
free((*node)->valor);
free(*node);
*node = NULL;
}
void Inserir(Arvore *raiz, int value) {
Arvore node = *raiz;
Arvore anterior = NULL;
if (*raiz == NULL) {
*raiz = CriarArvore(value);
return;
}
else {
while (node != NULL) {
anterior = node;
if (*node->valor > value) {
node = node->left;
}
else if (*node->valor < value) {
node = node->right;
}
else {
return;
}
}
if (*anterior->valor > value) {
anterior->left = CriarArvore(value);
}
else {
anterior->right = CriarArvore(value);
}
}
}
void ImprimirArvore(Arvore raiz, int nivel) {
int i;
if (raiz == NULL) {
for (i = 0; i < nivel; i++) {
printf("\t");
}
printf("*\n");
return;
}
ImprimirArvore(raiz->right, nivel + 1);
for (i = 0; i < nivel; i++) {
printf("\t");
}
printf("%d\n", *raiz->valor);
ImprimirArvore(raiz->left, nivel + 1);
}
Arvore Minimo(Arvore *raiz) {
Arvore node = *raiz;
while (node->left != NULL) {
node = node->left;
}
return node;
}
void DestruirNode(Arvore *raiz) {
Arvore node = *raiz;
if ((*raiz)->left == NULL && (*raiz)->right == NULL) {
DestruirArvore(raiz);
}
else if ((*raiz)->right == NULL) {
*raiz = (*raiz)->left;
DestruirArvore(raiz);
}
else {
*(*raiz)->valor = *Minimo((*raiz)->right)->valor;
ProcuraArvoreApaga(&(*raiz)->right, (*raiz)->valor);
}
}
void ProcuraArvoreApaga(Arvore *raiz, int *value) {
if (*raiz == NULL) {
return;
}
if (*(*raiz)->valor > *value) {
ProcuraArvoreApaga(&(*raiz)->right, value);
}
else if (*(*raiz)->valor < *value) {
ProcuraArvoreApaga(&(*raiz)->left, value);
}
else {
/*value = *(*raiz)->valor;*/
printf("%d", value);
DestruirNode(&raiz);
}
return 0;
}
int main(void) {
setlocale(LC_ALL, "Portuguese");
Arvore raiz = NULL;
int i = 0, escolha;
int value = NULL;
int var = NULL;
for (i = 1; i < 2; i++) {
printf("\t\tÁrvores binárias\n\n");
printf("Selecione a operação que deseja efetuar:\n");
printf("[1] Adicionar valor\n");
printf("[2] Vizualizar árvore\n");
printf("[3] Apagar valor/árvore\n");
printf("[4] Sair\n\n");
printf(">>");
scanf("%d", &escolha);
switch (escolha) {
case 1:
system("cls");
printf("Introduza o valor a adicionar à árvore:\n>>");
scanf("%d", &value);
Inserir(&raiz, value);// Adiciona na árvore
system("cls");
i = 0;
break;
case 2:
system("cls");
printf("\t\tVisualização da árvore\n\n");
ImprimirArvore(raiz, 10);// O 10 adiciona quantos níveis tem a árvore
i = 0;
break;
case 3:
system("cls");
printf("Introduza o valor que deseja apagar(um valor que não seja folha apagará os ramos e folhas abaixo dele):\n>>");
scanf("%d", &var);
ProcuraArvoreApaga(&raiz, &var);
system("cls");
i = 0;
break;
case 4:
break;
}
}
}

Sorting Simple Linked List - C

[UPTATED WITH ANSWER AT THE END] I tried many things but I still don't know how I can do any sorting with a simple linked list. It should be sorted like the number saved on each node goes from the lower till the higher one. What can I do?
I'm not allowed to sort the numbers as I save then on the list. The sorting must be made after the list is complete.
the code isn't completely ready yet
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define pi 3.14159265359
#define N 50
typedef struct lista{
char palavra[N];
int repeticao;
struct lista *prox;
} Lista;
Lista* lista_cria(){
return NULL;
}
int vazia(Lista *LISTA){
if(LISTA->prox == NULL) return 1;
else return 0;
}
void insere(Lista **lis, char *s){
Lista* novo = (Lista*) malloc (sizeof(Lista));
strcpy(novo->palavra, s);
novo->prox = NULL;
while (*lis)
lis = &(*lis)->prox;
*lis = novo;
}
Lista* retira(Lista* lis, char *s){
Lista* ant = NULL;
Lista* p = lis;
while(p != NULL && (strcmp(s, p->palavra) != 0)){
ant = p;
p = p->prox;
}
if(p == NULL) return lis;
if(ant == NULL) lis = p->prox;
else ant->prox = p->prox;
free(p);
return lis;
}
void imprimir_lista(Lista* lis){
Lista* p;
for(p = lis; p != NULL; p = p->prox)
printf("%s ", p->palavra);
printf("\n \n");
}
int busca(Lista* lis, char *s){
Lista *p;
int cont = 0;
for(p = lis; p != NULL; p = p->prox){
if(strcmp(p->palavra, s) == 0) cont++;
}
return cont;
}
Lista* repeticao(Lista* lis, int i){
Lista *p;
char s[50];
int cont;
printf("\n \n Doc%d", i);
for(p = lis; p != NULL; p = p->prox){
strcpy(s, p->palavra);
cont = busca(p, s);
printf(" \n\t %s: %d ", s, cont);
p->repeticao = cont;
}
return lis; /* return p*/
}
void liberar_lista(Lista *lis){
Lista *aux = lis;
while (aux != NULL) {
Lista *aux2 = aux->prox;
free(aux);
aux = aux2;
}
}
float produto_escalar (Lista *lis1, Lista *lis2) {
Lista *aux1 = lis1, *aux2 = lis2;
float resultado=0;
while (aux1 != NULL) {
while (aux2 != NULL) {
if (strcmp(aux1->palavra, aux2->palavra) == 0 ) {
resultado+=(aux1->repeticao*aux2->repeticao);
aux2 = aux2->prox;
break;
}
else {
aux2 = aux2->prox;
}
}
aux1 = aux1->prox;
aux2 = lis2;
}
return resultado;
}
float formula (Lista *lis1, Lista *lis2){
float resultado;
resultado = acos(produto_escalar(lis1, lis2)/(sqrt(produto_escalar(lis1, lis1))*sqrt(produto_escalar(lis2, lis2))));
resultado = (((resultado *50)*4)/pi)-100;
if (resultado<0){
resultado*=-1;
}
return resultado;
}
void checa_plagio (float resultado) {
if (resultado>=50) {
printf("\n O arquivo foi plagiado. \n\t Arquivo é %.3f%% parecido.", resultado);
}
else
printf("\n O arquivo não foi plagiado \n\t Arquivo é %.3f%% parecido.", resultado);
}
int main () {
char arquivo1[] = "doc1.txt", arquivo2[] = "doc2.txt";
char string[50];
double resposta;
FILE *fp1, *fp2;
Lista *lista1, *lista2;
lista1 = lista_cria();
lista2 = lista_cria();
fp1 = fopen (arquivo1, "r+") ;
if (fp1 == NULL) {
printf("\nErro. Não foi possível abrir o arquivo.\n");
return EXIT_FAILURE;
}
while(!feof(fp1)){
fscanf(fp1, "%s[A-Z a-z]", string);
insere(&lista1, string);
}
fclose(fp1);
fp2 = fopen (arquivo2, "r+") ;
if (fp2 == NULL) {
printf("\nErro. Não foi possível abrir o arquivo.\n");
return EXIT_FAILURE;
}
while(!feof(fp2)){
fscanf(fp2, "%s[A-Z a-z]", string);
insere(&lista2, string);
}
fclose(fp2);
/*imprimir_lista(lista1);
imprimir_lista(lista2);*/
lista1 = repeticao(lista1, 1);
lista2 = repeticao(lista2, 2);
resposta = formula (lista1, lista2);
checa_plagio(resposta);
liberar_lista(lista1);
liberar_lista(lista2);
return EXIT_SUCCESS;
}
[UPDATED WITH ANSWER]
THE CODE I USED TO SORT:
#define N 50
#include <stdlib.h>
#include <stdio.h>
typedef struct lista{
char palavra[N];
int repeticao;
struct lista *prox;
} Lista;
Lista* sort (Lista *lis) {
Lista *temp, *empurra;
Lista *aux1, *aux2;
Lista *guarda;
aux1 = NULL;
for (temp = lis; temp != NULL; temp = temp->prox){
aux2 = temp;
for (empurra=temp->prox; empurra != NULL; empurra = empurra->prox){
if (empurra->repeticao < temp->repeticao){
guarda = temp->prox;
temp->prox = empurra->prox;
if(guarda == empurra)
empurra->prox = temp;
else
empurra->prox = guarda;
if(aux2 != temp)
aux2->prox = temp;
if(aux1)
aux1->prox = empurra;
else
lis = empurra;
guarda = temp;
temp = empurra;
empurra = guarda;
}
aux2 = empurra;
}
aux1 = temp;
}
return lis;
}
int main (){
return 0;
}
I think the most learning approach that you can take, it's to think that the linked list is an array. With that approach you can simply, access the elements of the array and apply a sort algorithm (like bubble sort) and when make the swap of the elements using the pointer to the elements. With that would be just a matter to redirect the pointers (to next elements) for the right elements.
Also, pay attention to the particular cases of the sorts (the beginning and the end of list, in this case).
Here's a example:
Suppose that we have the structure for the linked list:
typedef struct list{
int n;
struct list *next;
} List;
And we want to sort the linked list using the int n, a code example would be something like this:
void sort (List * begin) {
List *currentElement, *previousElement;
int swapped = 1;
while (swapped) {
swapped = 1;
while (swapped != 0) {
swapped = 0;
currentElement = begin;
previousElement = NULL; //No previous element in the beginning of the list
while(currentElement->next != NULL) { //Has another element, it's not the end of the list
List *nextElement = currentElement->next;
if(currentElement->n > nextElement->n) {
//swapping the elements
if (previousElement == NULL) { //is the first element
List *auxPtr = nextElement->next;
nextElement->next = currentElement;
currentElement->next = auxPtr;
begin = nextElement; //nextElement is the first element of the list now
}
else {
previousElement->next = nextElement;
currentElement->nextElement->next;
nextElement->next = currentElement;
}
previousElement = nextElement; //The nextElement is 'behind' the currentElement so it should be the previousElement
swapped = 1; // a swap was made
//The elements where swapped so currentElement is already in the 'position' of the next element, there is no need to upload it value
}
else { // there is no need to swap, just walk foward in the list
previousElement = currentElement;
currentElement = nextElement;
}
}
}
}
}
I used a simple bubble sort for the sorting

Assignment from incompatible pointer type in Eclipse

I have seen many questions on this topic, but couldn't take much sense from them and couldn't compare it to my code. I'm not sure what I'm doing wrong, but it appears as a warning on Eclipse, and I think it might be what's making my function behave differently than it should.
The comments and variables are in portuguese, so if you need me to translate any part of it, or to tell you what each function should do, just tell me.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "grafo.h"
typedef struct _relemento
{
/** string armazenada */
char *nome;
int x, y, id;
struct _elemento *proximo;
} robot_lista;
typedef struct
{
robot_lista *raiz;
int tamanho;
} listarobots;
typedef struct _elemento
{
/** string armazenada */
int x;
int y;
int v;
struct _elemento *proximo;
} elemento_lista;
typedef struct
{
elemento_lista *raiz;
int tamanho;
} lista;
listarobots* listarobots_nova()
{
/* cria lista */
listarobots *lst = (listarobots*) malloc(sizeof(listarobots));
if(lst == NULL)
return NULL;
/* lista esta' vazia */
lst->raiz = NULL;
lst->tamanho = 0;
return lst;
}
robot_lista* novorobot_str(const char* valor, int x, int y, int id)
{
/* aloca memoria para a estrutura lista */
robot_lista *item = (robot_lista *) malloc(sizeof(robot_lista));
if(item == NULL)
return NULL;
/* aloca memoria para string */
item->nome = (char *) malloc((strlen(valor)+1)*sizeof(char));
if(item->nome == NULL)
{
free(item);
return NULL;
}
/* copia valor */
strcpy(item->nome, valor);
item->x=x;
item->y=y;
item->id=id;
/* item ainda nao tem proximo */
item->proximo = NULL;
return item;
}
int listarobots_insere(listarobots *lst, const char* valor, int x, int y,int id)
{
robot_lista *curr = NULL, *temp;
if (lst == NULL)
return -1;
temp = lst->raiz;
/* cria novo item */
curr = novorobot_str(valor, x, y, id);
if (curr == NULL)
return -1;
lst->tamanho++;
curr->proximo = temp;
lst->raiz = curr;
return 1;
}
int listarobot_pesquisa(listarobots *lst, const char* str, int* x, int* y, int *id)
{
int i=0;
robot_lista *aux;
if(lst == NULL)
return -1;
/* pesquisa sequencial */
for (aux = lst->raiz; aux != NULL; aux = aux->proximo, i++)
{
if (strcmp((aux->nome), str) == 0)
{
*x= aux->x;
*y= aux->y;
*id= aux->id;
return i;
}
}
return -1;
}
int listarobot_atribui(listarobots *lst, int pos, int x, int y)
{
int i=0;
robot_lista *aux;
if (lst == NULL || pos < 0)
return -1;
aux = lst->raiz;
/* procura item na posicao pos */
for (i = 0; i < pos && aux != NULL; i++)
aux = aux->proximo;
/* se aux e' NULL entao nao existe posicao pos */
if (aux == NULL)
return -1;
aux->x=x;
aux->y=y;
return pos;
}
lista* lista_nova()
{
/* cria lista */
lista *lst = (lista*) malloc(sizeof(lista));
if(lst == NULL)
return NULL;
/* lista esta' vazia */
lst->raiz = NULL;
lst->tamanho = 0;
return lst;
}
elemento_lista* novo_str(int x, int y, int v)
{
/* aloca memoria para a estrutura lista */
elemento_lista *item = (elemento_lista *) malloc(sizeof(elemento_lista));
if(item == NULL)
return NULL;
item->v=v;
item->x=x;
item->y=y;
/* item ainda nao tem proximo */
item->proximo = NULL;
return item;
}
int lista_insere(lista *lst, int x, int y, int v)
{
elemento_lista *curr = NULL, *temp;
if (lst == NULL)
return -1;
temp = lst->raiz;
/* cria novo item */
curr = novo_str(x,y,v);
if (curr == NULL)
return -1;
lst->tamanho++;
curr->proximo = temp;
lst->raiz = curr;
return v;
}
int lista_pesquisa(lista *lst, int x, int y)
{
int i=0;
elemento_lista *aux;
if(lst == NULL)
return -1;
/* pesquisa sequencial */
for (aux = lst->raiz; aux != NULL; aux = aux->proximo, i++)
{
if ((aux->x==x) && (aux->y==y))
{
return aux->v;
}
}
return -1;
}
int lista_xy (lista *lst, int v, int *x , int* y)
{
int i=0;
elemento_lista *aux;
if(lst == NULL)
return -1;
/* pesquisa sequencial */
for (aux = lst->raiz; aux != NULL; aux = aux->proximo, i++)
{
if ((aux->v==v))
{
*x=aux->x;
*y=aux->y;
return 1;
}
}
return -1;
}
void leitura(int *tamx,int *tamy,int *xminfinal, int* yminfinal, int *wx, int *wy, int *fimx, int *fimy, FILE * fp, grafo *robots, lista *celulas, listarobots *posicoes)
{
int naofaznada,tamanho=0, i, x, y, xmax, xmin, ymax, ymin, v=1,dest,poslst, origem,id=0;
char nome[16], aux;
xmax=xmin=ymax=ymin=0;
celulas=lista_nova();
lista_insere(celulas, 0,0,0);
fp = fopen("input.txt", "r");
robots = grafo_novo(tamanho,NAODIRECIONADO);
posicoes=listarobots_nova();
fscanf( fp, " %c", &aux);
while (aux!=EOF)
{
for (i=0;aux!= ',';i++)
{
nome[i]=aux;
nome[i+1]='\0';
fscanf(fp, " %c", &aux);
}
fscanf(fp, " %c", &aux);
poslst=listarobot_pesquisa(posicoes, nome, &x, &y, &naofaznada);
if(poslst==-1)
{
if(aux=='D')
{
x=0;
y=-1;
}
if(aux=='U')
{
x=0;
y=1;
}
if(aux=='L')
{
x=-1;
y=0;
}
if(aux=='R')
{
x=1;
y=0;
}
listarobots_insere(posicoes, nome, x, y, id);
id++;
origem=0;
if(x>xmax) xmax=x;
if(x<xmin) xmin=x;
if(y>ymax) ymax=y;
if(y<ymin) ymin=y;
if(lista_pesquisa(celulas, x, y)==-1)
{
lista_insere(celulas, x, y, v);
dest=v;
v++;
grafo_adiciona(robots, 0, dest);
if(lista_pesquisa(celulas, (x+1),y)!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, (x+1), y));
if(lista_pesquisa(celulas, (x-1),y)!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, (x-1), y));
if(lista_pesquisa(celulas, x,(y+1))!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, x, (y+1)));
if(lista_pesquisa(celulas, x,(y-1))!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, x, (y-1)));
}
}
else
{
origem=lista_pesquisa(celulas,x, y);
if(aux=='D')
{
y=y-1;
}
if(aux=='U')
{
y=y+1;
}
if(aux=='L')
{
x=x-1;
}
if(aux=='R')
{
x=x+1;
}
listarobot_atribui(posicoes, poslst, x, y);
}
if(x>xmax) xmax=x;
if(x<xmin) xmin=x;
if(y>ymax) ymax=y;
if(y<ymin) ymin=y;
if(lista_pesquisa(celulas, x, y)==-1)
{
lista_insere(celulas, x, y, v);
dest=v;
v++;
grafo_adiciona(robots, origem, dest);
if(lista_pesquisa(celulas, (x+1),y)!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, (x+1), y));
if(lista_pesquisa(celulas, (x-1),y)!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, (x-1), y));
if(lista_pesquisa(celulas, x,(y+1))!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, x, (y+1)));
if(lista_pesquisa(celulas, x,(y-1))!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, x, (y-1)));
}
if(fscanf(fp, " %c", &aux)==EOF) break;
if(aux=='?')
{
*wx=x;
*wy=y;
if(fscanf(fp, " %c", &aux)==EOF) break;
}
if(aux=='!')
{
*fimx=x;
*fimy=y;
if(fscanf(fp, " %c", &aux)==EOF) break;
}
}
*tamx= xmax-xmin+1;
*tamy= ymax-ymin +1;
*xminfinal=xmin;
*yminfinal=ymin;
return ;
}
void mapeamento(FILE * out, int x, int y, int ymin, int xmin, int wx, int wy, int fimx, int fimy, lista* celulas )
{
int xatual, yatual;
for(yatual=ymin+ y-1; yatual!=ymin-1;yatual--)
{
for(xatual=xmin; xatual!=xmin+x; xatual++)
{
if((xatual==0) && (yatual==0)) fprintf(out," e ");
else if((xatual==wx)&&(yatual==wy)) fprintf(out, " w ");
else if((xatual==fimx)&&(yatual==fimy)) fprintf(out, " s ");
else if(lista_pesquisa(celulas, x, y)==-1) fprintf(out, " * ");
else if(lista_pesquisa(celulas, x, y)!=-1)fprintf(out, " . ");
if(xatual==fimx) fprintf(out, "\n");
}
}
return;
}
void caminhos(int wx, int wy, int fimx, int fimy, lista* celulas, FILE *fp, FILE *out, grafo *robots, listarobots* posicoes)
{
int restantes,nfnx,nfny,i,id,is,antx,anty,novox,novoy,tamanhocaminho1,tamanhocaminho2, *caminho1, *caminho2, *posrobots;
char *caminho,nome[16], aux;
caminho1=grafo_bfs(robots, 0, lista_pesquisa(celulas, wx, wy), &tamanhocaminho1);
caminho2=grafo_bfs(robots, lista_pesquisa(celulas, wx, wy), lista_pesquisa(celulas, fimx, fimy), &tamanhocaminho2);
caminho= malloc((tamanhocaminho1+tamanhocaminho2)*sizeof(char));
antx=0;
anty=0;
is=0;
for(i=1; i<tamanhocaminho1; i++, is++)
{
lista_xy(celulas, caminho1[i], &novox, &novoy);
if((novox-antx)==1) caminho[is]= 'R';
else if((novox-antx)==-1) caminho[is]= 'L';
else if((novoy-anty)==-1) caminho[is]= 'D';
else if((novoy-anty)==1) caminho[is]= 'U';
antx=novox;
anty=novoy;
}
for(i=1; i<tamanhocaminho2; i++, is++)
{
lista_xy(celulas, caminho1[i], &novox, &novoy);
if((novox-antx)==1) caminho[is]= 'R';
else if((novox-antx)==-1) caminho[is]= 'L';
else if((novoy-anty)==-1) caminho[is]= 'D';
else if((novoy-anty)==1) caminho[is]= 'U';
antx=novox;
anty=novoy;
}
caminho[is]='\0';
fprintf(out, "\n\n%s\n", caminho);
free(caminho1);
free(caminho2);
fclose(fp);
fp=fopen("input.txt", "r");
restantes=posicoes->tamanho;
posrobots=calloc (posicoes->tamanho, sizeof(int));
fscanf(fp, " %c", &aux);
while (aux!=EOF)
{
for (i=0;aux!= ',';i++)
{
nome[i]=aux;
nome[i+1]='\0';
fscanf(fp, " %c", &aux);
}
fscanf(fp, " %c", &aux);
listarobot_pesquisa(posicoes, nome, &nfnx, &nfny, &id);
if(posrobots[id]==-1) nfnx=1;
else if(caminho[posrobots[id]]==aux) posrobots[id]++;
else
{
posrobots[id]=-1;
restantes--;
}
if(posrobots[id]==is) fprintf(out, "%s\n", nome);
fscanf(fp, " %c", &aux);
if(aux=='?')
{
fscanf(fp, " %c", &aux);
}
if(aux=='!')
{
fscanf(fp, " %c", &aux);
}
}
if(restantes==0) fprintf(out, "0\n");
}
void output()
{
}
int main()
{
FILE *fp, *out;
grafo *robots;
lista *celulas;
listarobots *posicoes;
celulas=(lista * )malloc(sizeof(lista));
robots=(grafo * )malloc(sizeof(grafo));
posicoes=(listarobots * )malloc(sizeof(listarobots));
fp=(FILE * )malloc(sizeof(FILE));
out=(FILE * )malloc(sizeof(FILE));
int x,y,xmin, ymin,wx,wy,fimx,fimy;
out=fopen("output.txt", "w");
leitura(&x, &y, &xmin, &ymin,&wx, &wy, &fimx, &fimy, fp, robots, celulas, posicoes);
fprintf(out,"largura:%d, altura:%d\n", x, y );
mapeamento(out, x, y, ymin, xmin, wx, wy, fimx, fimy, celulas);
//caminhos(wx, wy,fimx, fimy,celulas, fp, out, robots, posicoes);
return 0;
}
the extra includes dont make a difference, I've checked and the errors are on this block of code, but just in case, I'll post here the code for the include "grafo.h"
#include <stdio.h>
#include <stdlib.h>
#include "grafo.h"
/* cria no da lista de adjacencias */
lista_no* cria_no(int v)
{
lista_no* novo = (lista_no*)malloc(sizeof(lista_no));
if(!novo)
return NULL;
novo->vertice = v;
novo->proximo = NULL;
return novo;
}
/* cria grafo com n vertices */
grafo* grafo_novo(int n, tipo_grafo tipo)
{
grafo* g = (grafo*)malloc(sizeof(grafo));
lista_no novo;
if(g == NULL)
return NULL;
g->tamanho = 1;
g->tipo = tipo;
/* cria array de listas de adjacencias */
g->adjacencias = (lista_adj*)calloc(n, sizeof(lista_adj));
if(g->adjacencias == NULL)
{
free(g);
return NULL;
}
g->adjacencias[0].inicio=NULL;
return g;
}
/* apaga grafo e liberta memoria */
void grafo_apaga(grafo* g)
{
if(g == NULL)
return;
if(g->adjacencias != NULL)
{
int v;
for (v = 0; v < g->tamanho; v++)
{
while (g->adjacencias[v].inicio)
{
lista_no* aux = g->adjacencias[v].inicio;
g->adjacencias[v].inicio = g->adjacencias[v].inicio->proximo;
free(aux);
}
}
free(g->adjacencias);
}
free(g);
}
/* adiciona uma aresta ao grafo*/
void grafo_adiciona(grafo *g, int origem, int dest)
{
lista_no* novo,*aux,*ant;
if (g == NULL || grafo_existe(g, origem, dest))
return;
/* adiciona uma aresta de origem para dest na lista de adjacencias */
novo = cria_no(dest);
novo->proximo = NULL;
g->adjacencias = (lista_adj*)realloc(g->adjacencias, (g->tamanho+1)*sizeof(lista_adj));
g->adjacencias[dest].inicio=NULL;
g->tamanho++;
ant= aux =g->adjacencias[origem].inicio;
if(ant==NULL) g->adjacencias[origem].inicio=novo;
else
{
aux=ant->proximo;
while(aux!=NULL)
{
ant=aux;
aux=ant->proximo;
}
ant->proximo=novo;
}
g->adjacencias[origem].tamanho++;
if(g->tipo == NAODIRECIONADO)
{
/* adiciona tambem aresta de dest para origem */
novo = cria_no(origem);
novo->proximo = NULL;
ant= aux =g->adjacencias[dest].inicio;
if(ant==NULL) g->adjacencias[dest].inicio=novo;
else
{
aux=ant->proximo;
while(aux!=NULL)
{
ant=aux;
aux=ant->proximo;
}
ant->proximo=novo;
}
g->adjacencias[dest].tamanho++;
}
}
/* remove uma aresta do grafo*/
void grafo_remove(grafo *g, int origem, int dest)
{
lista_no *aux, *prev;
if (g == NULL || g->adjacencias[origem].inicio == NULL)
return;
aux = g->adjacencias[origem].inicio;
/* caso especial: primeiro no' da lista */
if(aux->vertice == dest)
{
g->adjacencias[origem].inicio = aux->proximo;
free(aux);
}
else
{
prev = aux;
aux = aux->proximo;
while(aux != NULL)
{
if(aux->vertice == dest)
{
prev->proximo = aux->proximo;
free(aux);
break;
}
prev = aux;
aux = aux->proximo;
}
}
if(g->tipo == NAODIRECIONADO)
{
/* remove tambem aresta de dest para origem */
/* caso especial: primeiro no' da lista */
aux = g->adjacencias[dest].inicio;
if(aux->vertice == origem)
{
g->adjacencias[dest].inicio = aux->proximo;
free(aux);
}
else
{
prev = aux;
aux = aux->proximo;
while(aux != NULL)
{
if(aux->vertice == origem)
{
prev->proximo = aux->proximo;
free(aux);
break;
}
prev = aux;
aux = aux->proximo;
}
}
}
}
/* verifica se existe uma aresta entre os vertices origem e dest */
int grafo_existe(grafo *g, int origem, int dest)
{
if (g == NULL)
return 0;
lista_no* aux = g->adjacencias[origem].inicio;
while (aux)
{
if(aux->vertice == dest)
return 1;
aux = aux->proximo;
}
return 0;
}
/* imprime as listas de adjacencias do grafo */
void grafo_imprime(grafo* g)
{
int i;
for (i = 0; i < g->tamanho; i++)
{
lista_no* aux = g->adjacencias[i].inicio;
printf("%d: ", i);
if(aux)
{
printf("%d", aux->vertice);
aux = aux->proximo;
while (aux)
{
printf("->%d", aux->vertice);
aux = aux->proximo;
}
}
printf("\n");
}
}
int dfs_helper(grafo *g, int inicio, int fim, int profundidade, int *visitados)
{
int i, d;
if(visitados[inicio])
return 0;
visitados[inicio] = profundidade;
if(inicio == fim)
return profundidade;
for(i=0; i < g->tamanho; i++)
{
if(grafo_existe(g, inicio, i))
{
d = dfs_helper(g, i, fim, profundidade + 1, visitados);
if(d)
return d;
}
}
visitados[inicio] = 0;
return 0;
}
/* retorna caminho entre origem e dest usando depth-first search (DFS)
n guarda o tamanho do caminho
nao garante caminho mais curto */
int* grafo_dfs(grafo *g, int inicio, int fim, int *n)
{
int *visitados, *caminho;
int profundidade, i, ret_i;
if(g==NULL)
return 0;
visitados = calloc(g->tamanho, sizeof(int));
profundidade = dfs_helper(g, inicio, fim, 1, visitados);
if(profundidade == 0)
{
free(visitados);
*n=0;
return NULL;
}
/* reconstrucao do caminho */
caminho = calloc(profundidade, sizeof(int));
for (ret_i = 0; ret_i < profundidade; ret_i++)
for (i = 0; i< g->tamanho; i++)
if(visitados[i] == ret_i + 1)
{
caminho[ret_i] = i;
break;
}
*n = profundidade;
free(visitados);
return caminho;
}
/* retorna caminho entre origem e dest usando breadth-first search (BFS)
n guarda o tamanho do caminho
garante caminho mais curto */
int* grafo_bfs(grafo *g, int inicio, int fim, int *n)
{
int *caminho, *visitados, *fila;
int profundidade, i, j, fila_inicio = 0, fila_fim=0;
if(g==NULL)
return 0;
visitados = calloc(g->tamanho, sizeof(int));
fila = calloc(g->tamanho, sizeof(int));
for(i = 0; i < g->tamanho; i++)
visitados[i] = -1;
visitados[inicio] = inicio;
fila[fila_fim++] = inicio;
while(fila_inicio != fila_fim)
{
i = fila[fila_inicio];
fila_inicio = (fila_inicio + 1) % g->tamanho;
for(j = 0; j < g->tamanho; j++)
if(grafo_existe(g, i, j) && visitados[j] == -1)
{
visitados[j] = i;
fila[fila_fim] = j;
fila_fim = (fila_fim + 1) % g->tamanho;
}
}
/* reconstrucao do caminho */
profundidade = 0;
if(visitados[fim] >= 0)
{
int tmp = fim;
profundidade = 1;
while(visitados[tmp] != tmp)
{
profundidade++;
tmp = visitados[tmp];
}
caminho = malloc(profundidade * sizeof(int));
tmp = fim;
i = 0;
while(i++ < profundidade)
{
caminho[profundidade - i] = tmp;
tmp = visitados[tmp];
}
}
free(fila);
free(visitados);
*n=profundidade;
return caminho;
}
And the warnings are:
Description Resource Path Location Type
assignment from incompatible pointer type [enabled by default] trabalho.c /trabalho/src line 110 C/C++ Problem
assignment from incompatible pointer type [enabled by default] trabalho.c /trabalho/src line 135 C/C++ Problem
assignment from incompatible pointer type [enabled by default] trabalho.c /trabalho/src line 95 C/C++ Problem
I appreciate any and all the help you can offer. I am still pretty new at programming and this warnings are completely messing with my mind.
It looks like you're assigning proximo (which are pointers to _elemento) to variables that are pointers to robot_lista.

Eliminate node function from tree doesn't work in C

I have to eliminate a node from the tree. I first tried to eliminate the node root, so I don't have to search the node and it works. But then I tried to do it by searching, and when the function calls itself, the program freezes after it passes the first if-statement...
The problem is in the function, void Eliminar(struct arbol *tree, int valor);:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct arbol
{
int numero;
struct arbol *izq;
struct arbol *der;
};
struct arbol *raiz = NULL;
struct arbol *eliminador = NULL;
int encontrado = 0;
int right = 0, left = 0;
int crear_arbol(int dato);
struct arbol * crear_nodo(int valor);
void ImprimeDNI (struct arbol *tree);
void ImprimeIND (struct arbol *tree);
void ImprimeNDI (struct arbol *tree);
void Buscar (struct arbol *tree, int valor);
void Eliminar (struct arbol *tree,int valor);
int Eliminaroot ();
int Eliminarright(struct arbol *localizador);
int Eliminarleft(struct arbol *localizador);
int main ()
{
int n, i;
char opcion;
int numero;
puts("Ingrese la cantidad de numeros a ingresar");
scanf("%d", &n);
int numeros[n];
puts("Ingrese los numeros separados por espacio o enter");
for(i = 0; i < n; i++)
{
scanf("%d",&numeros[i]);
}
for(i = 0; i < n; i++)
{
crear_arbol(numeros[i]);
}
puts("");
system("pause");
system("cls");
do
{
encontrado = 0;
puts("******** OPCIONES ********");
puts("|B o b| Para buscar un numero");
puts("|E o e| Eliminar un nodo");
puts("|I o i| Imprimir de las 3 formas principales");
fflush(stdin);
opcion = getch();
switch(opcion)
{
case 'B': case 'b': puts("Ingrese el numero a buscar"); scanf("%d",&numero); Buscar(raiz,numero);
if(encontrado == 0) {puts("El numero no esta en el arbol");} break;
case 'E': case 'e': puts("Ingrese el numero a eliminar"); scanf("%d", &numero);
if(raiz->numero == numero)
{
Eliminaroot();
}
else
{
Eliminar(raiz,numero);
if(right == 0 && left == 0)
{
puts("No se encontro el numero");
}
if(right == 1)
{
Eliminarright(eliminador);
}
if(left == 1)
{
Eliminarleft(eliminador);
}
}
break;
case 'I': case 'i': ImprimeDNI(raiz); puts(""); ImprimeIND(raiz); puts(""); ImprimeNDI(raiz); puts(""); break;
default: puts("Opcion Invalida"); break;
}
puts("");
system("pause");
system("cls");
}while (opcion != 'T' || opcion != 't');
return 0;
}
int crear_arbol(int dato)
{
struct arbol *recorrer = raiz;
struct arbol *nuevo;
if(raiz == NULL)
{
raiz = crear_nodo(dato);
return 1;
}
else
{
nuevo = crear_nodo(dato);
}
while (1) {
if(recorrer->numero <= nuevo->numero)
{
if(recorrer->der == NULL)//si las ramas de donde esta el puntero que recorre son NULL, significa
{ //que es la ultima comparacion
recorrer->der = nuevo;
break;
}
recorrer = recorrer->der;
}
else
{
if(recorrer->izq == NULL)//lo mismo que el if de arriba
{
recorrer->izq = nuevo;
break;
}
recorrer = recorrer->izq;
}
}//while
return 1;
}
struct arbol * crear_nodo(int valor)
{
struct arbol *aux;
aux = (struct arbol*)malloc(sizeof(struct arbol));
aux->numero = valor;
aux->izq = NULL;
aux->der = NULL;
return aux;
}
void ImprimeDNI (struct arbol *tree)
{
if(!tree)
return;
ImprimeDNI(tree->der);
printf("%d, ", tree->numero);
ImprimeDNI(tree->izq);
}
void ImprimeIND (struct arbol *tree)
{
if(!tree)
return;
ImprimeIND(tree->izq);
printf("%d, ", tree->numero);
ImprimeIND(tree->der);
}
void ImprimeNDI (struct arbol *tree)
{
if(!tree)
return;
printf("%d, ", tree->numero);
ImprimeNDI(tree->der);
ImprimeNDI(tree->izq);
}
void Buscar (struct arbol *tree, int valor)
{
if(tree->numero == valor)
{printf("El numero si se encuentra en el arbol"); encontrado = 1;}
if(!tree)
return;
Buscar(tree->der, valor);
Buscar(tree->izq,valor);
}
int Eliminaroot ()
{
int encontrado = 0;
struct arbol *aux = raiz;
struct arbol *buscador = raiz->der;
for(; buscador->der != NULL ; buscador = buscador->der)
{
if(buscador->izq != NULL)
{
encontrado = 1;
for(; buscador->izq->izq != NULL ; buscador = buscador->izq)
{
}
break;
}//if
}
if(encontrado == 0)
{
if(raiz->der == NULL)
{
raiz = aux->izq;
raiz->izq = aux->izq->izq;
raiz->der = aux->izq->der;
}
else
{
raiz = aux->der;
raiz->izq = aux->izq;
raiz->der = aux->der->der;
free(aux);
}
}
else
{
raiz = buscador->izq;
raiz->der = aux->der;
raiz->izq = aux->izq;
buscador->izq = NULL;
free(aux);
}
return 1;
}
void Eliminar (struct arbol *tree, int valor)
{
if(tree->izq->numero == valor)
{
eliminador = tree;
left = 1;
}
puts("AAAA");
if(tree->der->numero == valor)
{
eliminador = tree;
right = 1;
}
if(!tree)
return;
Eliminar(tree->der, valor);
Eliminar(tree->izq, valor);
}
int Eliminarright(struct arbol *localizador)
{
return 1;
}
int Eliminarleft(struct arbol *localizador)
{
return 1;
}*
As Nick suggested, you should check that tree is valid at the beginning of Eliminar. However, if the first if statement executes fine, tree can't be NULL. tree->der can, though - you should check that too before dereferencing it. And of course, the same for tree->izq in the first if - just because it isn't NULL the very first time you call this function, don't assume it never will.
A few further notes: you are searching for the node having the value valor in Eliminar (which is thus a bad name - you aren't eliminating the node there, only marking it for later removal).
If you find it, there is no point continuing the search, so you can return right away from both if branches.
Moreover, you handle separately the cases when you find valor in the left or right subtree, by setting the left or right flags, and calling Eliminarleft or Eliminarright accordingly. It would be much simpler to store directly the left or right subtree to be removed, so then you can drop the two flags and the two removal methods:
void Eliminar (struct arbol *tree, int valor)
{
if(!tree)
return;
if(tree->izq && tree->izq->numero == valor)
{
eliminador = tree->izq;
return;
}
puts("AAAA");
if(tree->der && tree->der->numero == valor)
{
eliminador = tree->der;
return;
}
Eliminar(tree->der, valor);
Eliminar(tree->izq, valor);
}
...
Eliminar(raiz,numero);
if(!eliminador)
{
puts("No se encontro el numero");
}
else
{
Eliminar(eliminador);
}
This is cleaner, but we can go even further. Notice that you are checking the left and right subtrees in Eliminar, then recursing on the same. It suffices instead to check only tree itself, then recurse:
void Eliminar (struct arbol *tree, int valor)
{
if(!tree)
return;
if(tree->numero == valor)
{
eliminador = tree;
return;
}
puts("AAAA");
Eliminar(tree->der, valor);
Eliminar(tree->izq, valor);
}
You're not checking the tree pointer at the top of your function, so could be causing an access violation on a null pointer. Move your if (!tree) return; check to the top of the function.
#PéterTörök's answer gets you part of the way there. It looks to me like you have a standard binary tree setup with "value less than" on the left and "value greater than" on the right (or perhaps >= if you allow duplicates).
It would be awfully good to get rid of the global variables, though (Eliminar sets eliminador and also a left/right flag), which you can do by using pointers-to-pointers. Instead of having Eliminar take a tree node, it can take a pointer to a tree node, and update it when removing a node. Furthermore, once a node has been removed, you can stop:
int Eliminar(struct arbol **tree_p, int valor)
{
struct arbol *tree = *tree_p;
if (!tree)
return 0; /* nothing to remove */
if (tree->numero == valor) {
/* this is the node to remove */
*tree_p = rewrite(tree); /* rewrite subtree from here down, and update */
return 1; /* indicate that we're done */
}
/* didn't find the node to remove ... use left or right subtree for next attempt */
tree_p = tree->numero > valor ? &tree->der : &tree->izq;
return Eliminar(tree_p, valor);
}
(not sure if I got left/right correct above; I leave that for you to work on :-) ).
It's easy now to turn the recursion into iteration. The hard part is rewrite(), because you can have both left and right sub-trees of tree. If you have only one, it's easy, but if you have both, it's not so easy anymore. Again, I leave that as an exercise... :-)
You can have Eliminar return the actual removed tree node (or NULL if valor is not in the tree); that can be useful in some cases. In either case, you just do: result = Eliminar(&root, valor); to update the root node and get a success/fail indicator.

Resources