Compiler crashing due to linked list error (?) - c

Sim simulacao(Sim lista, int lin, int col, int dim)
{
int conta;
int contador_conta;
int x, y; //x=linha, y=col
char tipo;
int pop1;
conta = ((lin * col) * dim) / 100; //nr de células a serem preenchidas
contador_conta = conta;
pop1 = conta / 2;
while (contador_conta != 0)
{
contador_conta--;
x = numero_random(1, lin);
y = numero_random(1, col);
if (pop1 != 0)
{
tipo = 'O';
printf("%d\n", x);
lista = adiciona(lista, x, y, tipo);
printf("%d\n", x);
pop1--;
}
else
{
tipo = 'X';
lista = adiciona(lista, x, y, tipo);
}
}
return lista;
}
Sim adiciona(Sim lista, int x, int y, char tipo)
{
Sim novo, aux;
novo = (Sim)malloc(sizeof(lista));
if (novo == NULL) //verifica se alocou o espaço com sucesso
{
printf("Erro na alocacao de memoria!\n");
return lista;
}
printf("%d\n", x);
novo->linha = x;
novo->coluna = y;
printf("%d\n", x);
novo->tipo = tipo;
novo->prox = NULL;
if (lista == NULL)
{
lista = novo; //se a lista estiver vazia, insere no topo da lista
}
else
{
aux = lista; //insere no fim da lista
while (aux->prox != NULL)
aux = aux->prox;
aux->prox = novo;
printf("%d\n", x);
}
printf("%d\n", x);
return lista;
}
I'm having a problem when compiling my code, it crashes after running the adiciona function 2 times. I've placed some printf's in order to check when it crashes, however i've been looking for the errors and i can't find it :/
Any thoughts on what's the problem?
picture of the crash/error

novo=(Sim)malloc(sizeof(lista));
You are allocating for the pointer size not for the pointee. Change this to:
novo = malloc(sizeof *lista);

Related

Trying to limit a list in 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;
};

List vector print does not work

I'm doing a hash table, where I have a one vector with a list inside each node of it. But when I go to print it does not appear the items that are within the list, and if I try to put more than one element in the list, it gives segmentation failure in the second. Below is the code and the result:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
enum erro {
semErro = 0, posInv = 1, listaCheia = 2, listaVazia = 3, existe = 4, naoExiste = 5
};
typedef struct no{
char nome[100];
char telefone[20];
struct no *prox;
} nodo;
typedef struct{
int tamanho;
nodo *inicio;
} lista;
typedef struct {
int tamanhoTabelaHash;
int colisoes;
lista* vetor;
} tabela;
///////////////////Chamada de Funções///////////////////
lista *novaLista();
tabela *criaTabela(int tam);
int insereTabela(tabela *tabela, char *entraNome, char *entraTelefone);
int insereNoInicioI(lista *lista,char *entraNome, char *entraTelefone);
int hash1(char *entraNome, int tam);
void imprime(lista *lista);
void imprimeTabela(tabela *tabela);
///////////////////Funções Lista///////////////////
void imprime(lista *lista){
int i;
nodo *no; //<<<<<Possível local do erro>>>>>
puts("Lista: \n");
for (i = 0; i < lista->tamanho; i++) {
printf("Nome: %s Telefone: %s\n",no->nome,no->telefone);
no=no->prox;
}
}
lista *novaLista(){
lista *l = (lista*)malloc(sizeof(lista));
l->tamanho=0;
l->inicio=NULL;
return l;
}
int insereNoInicioI(lista *lista,char *entraNome, char *entraTelefone){
nodo *novo=(nodo *)malloc(sizeof(nodo));
strcpy(novo->nome,entraNome);
strcpy(novo->telefone,entraTelefone);
novo->prox = lista->inicio;
lista->inicio = novo;
lista->tamanho++;
return semErro;
}
tabela *criaTabela(int tam) {
if( tam < 1 ) return NULL;
tabela *table = (tabela *)malloc(sizeof(tabela));
table->tamanhoTabelaHash = tam;
table->colisoes = 0;
for (int i = 0; i < 10; i++) {
table[i].vetor = NULL;
}
return table;
}
void imprimeTabela(tabela *tabela) {
int i;
printf("\nTabela: \n");
for (i = 0; i < tabela->tamanhoTabelaHash ; i++) {
printf("\nindice[%d]:", i);
if(tabela[i].vetor!=NULL){
imprime(tabela[i].vetor);
}
}
}
int insereTabela(tabela *tabela, char *entraNome, char *entraTelefone){
int pos = 0;
pos = hash1(entraNome,10000);//Função que retorna uma posição( no caso 8 para o primeiro nome e 6 para o segundo e terceiro
}
if(tabela[pos].vetor==NULL){
lista *list = novaLista();
tabela[pos].vetor = list;
}
nodo *novo=(nodo *)malloc(sizeof(nodo));
insereNoInicioI(tabela[pos].vetor, entraNome, entraTelefone);
return semErro;
}
int main(){
setlocale(LC_ALL, "Portuguese");
tabela *table = criaTabela(10);
char nome[100] = "Maria Cláudia Feliz";
char telefone[20] = "(53)98401-8583";
char nome1[100] = "Everton Almeida";
char telefone1[20] = "(53)90000-8583";
char nome2[100] = "Everton Almeida";
char telefone2[20] = "(53)90000-8583";
insereTabela(table,nome,telefone);
insereTabela(table,nome1,telefone1);
insereTabela(table,nome2,telefone2);
imprimeTabela(table);
return semErro;
}
Resultado:
Tabela:
indice[0]:
indice[1]:
indice[2]:
indice[3]:
indice[4]:
indice[5]:
indice[6]:Lista:
Nome: Telefone: //<<<<Deveria imprimir o nome e telefone>>>>
Nome: Telefone: //<<<<Deveria imprimir o nome e telefone>>>>
indice[7]:
indice[8]:Lista:
//<<<<Deveria imprimir o nome e telefone>>>>
Falha de segmentação(imagem do núcleo gravada)
If you can help, thank you.
You have at least one serious problem here:
tabela *criaTabela(int tam) {
if (tam < 1) return NULL;
// you allocate space for 1 tabela
tabela *table = (tabela *)malloc(sizeof(tabela));
table->tamanhoTabelaHash = tam;
table->colisoes = 0;
// but here you write to 10 tabelas ....
for (int i = 0; i < 10; i++) {
table[i].vetor = NULL;
}
return table;
}
You if you write to 10 tabelas, you should allocate space for 10 tabelas:
tabela *table = (tabela *)malloc(sizeof(tabela) * 10);
The code in your answer yields in undefined bahaviour. In other works it may appear to work. Google "undefined bahaviour".
There may be more problems elsewhere in your code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
enum erro {
semErro = 0, posInv = 1, listaCheia = 2, listaVazia = 3, existe = 4, naoExiste = 5
};
typedef struct no{
char nome[100];
char telefone[20];
struct no *prox;
} nodo;
typedef struct{
int tamanho;
nodo *inicio;
} lista;
typedef struct {
int tamanhoTabelaHash;
int colisoes;
lista* vetor;
} tabela;
///////////////////Chamada de Funções///////////////////
lista *novaLista();
tabela *criaTabela(int tam);
int insereTabela(tabela *tabela, char *entraNome, char *entraTelefone);
int insereNoInicioI(lista *lista,char *entraNome, char *entraTelefone);
int hash1(char *entraNome, int tam);
void imprime(lista *lista);
void imprimeTabela(tabela *tabela);
///////////////////Funções Lista///////////////////
void imprime(lista *lista){
int i;
nodo *no = lista-> inicio;
puts("Lista: \n");
for (i = 0; i < lista->tamanho; i++) {
printf("Nome: %s Telefone: %s\n",no->nome,no->telefone);
no=no->prox;
}
}
lista *novaLista(){
lista *l = (lista*)malloc(sizeof(lista));
l->tamanho=0;
l->inicio=NULL;
return l;
}
int insereNoInicioI(lista *lista,char *entraNome, char *entraTelefone){
nodo *novo=(nodo *)malloc(sizeof(nodo));
strcpy(novo->nome,entraNome);
strcpy(novo->telefone,entraTelefone);
novo->prox = lista->inicio;
lista->inicio = novo;
lista->tamanho++;
return semErro;
}
tabela *criaTabela(int tam) {
if( tam < 1 ) return NULL;
tabela *table = (tabela *)malloc(sizeof(tabela)*10);
table->tamanhoTabelaHash = tam;
table->colisoes = 0;
for (int i = 0; i < 10; i++) {
table[i].vetor = NULL;
}
return table;
}
void imprimeTabela(tabela *tabela) {
int i;
printf("\nTabela: \n");
for (i = 0; i < tabela->tamanhoTabelaHash ; i++) {
printf("\nindice[%d]:", i);
if(tabela[i].vetor!=NULL){
imprime(tabela[i].vetor);
}
}
}
int hash1(char *string, int tam) {
int tamanho = strlen(string);
unsigned soma = 0;
for (int i = 0; i < tamanho; i++) {
soma = soma * 251 + string[i];
}
return soma % tam;
}
int insereTabela(tabela *tabela, char *entraNome, char *entraTelefone){
int pos = 0;
pos = hash1(entraNome,10);
if(tabela[pos].vetor==NULL){
lista *list = novaLista();
tabela[pos].vetor = list;
}
nodo *novo=(nodo *)malloc(sizeof(nodo));
insereNoInicioI(tabela[pos].vetor, entraNome, entraTelefone);
return semErro;
}
int main(){
setlocale(LC_ALL, "Portuguese");
tabela *table = criaTabela(10);
char nome[100] = "Maria Cláudia Feliz";
char telefone[20] = "(53)98401-8583";
char nome1[100] = "Everton Almeida";
char telefone1[20] = "(53)90000-8583";
char nome2[100] = "Everton Almeida";
char telefone2[20] = "(53)90000-8583";
insereTabela(table,nome,telefone);
insereTabela(table,nome1,telefone1);
insereTabela(table,nome2,telefone2);
imprimeTabela(table);
return semErro;
}
Resultado:
indice[0]:
indice[1]:
indice[2]:Lista:
Nome: Everton Almeida Telefone: (53)90000-8583
indice[3]:
indice[4]:
indice[5]:Lista:
Nome: Everton Telefone: (53)90000-8583
indice[6]:
indice[7]:
indice[8]:Lista:
Nome: Maria Cláudia Feliz Telefone: (53)98401-8583
indice[9]:
Thanks to all comments THIS IS THE CODE WORKING, but I have one more doubt, because the name clause goes wrong if the setlocale (LC_ALL, "Portuguese");

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