Foros del Web » Programación para mayores de 30 ;) » C/C++ »

ayuda con listas dinamicas en C :)

Estas en el tema de ayuda con listas dinamicas en C :) en el foro de C/C++ en Foros del Web. Veran tengo el siguiente código pero me falla al intentar insertar en orden me sale mi error favorito segmentation fault la clase solo tuve 1 ...
  #1 (permalink)  
Antiguo 12/04/2010, 19:06
 
Fecha de Ingreso: marzo-2010
Mensajes: 10
Antigüedad: 14 años, 1 mes
Puntos: 0
ayuda con listas dinamicas en C :)

Veran tengo el siguiente código pero me falla al intentar insertar en orden me sale mi error favorito segmentation fault la clase solo tuve 1 hora asi que no entendi bn mi clase se lo que significa el error pero no se porque me lo da :S me podrian ayudar porfavor aca dejo mi código y antes que lo olvide al eliminar datos mi código no me funciona para el primer y último nodo

Código:
/*  ************************************ 
    Programa que crea una lista simplemente ligada insertando nodos al inicio de la lista, y
    elimina el nodo que esta al final de la lista, ademas incluye una rutina que permite listar el contenido
    de la lista ligada.
    ************************************ */
#include <stdio.h>
#include <stdlib.h>

typedef struct n{
       int dato;
       struct n *sig;
       }NODO;
 
NODO *raiz;

void insertaInicio(int d) {
  NODO *aux;
  
  aux=(NODO *)malloc(sizeof(NODO));
  aux->dato=d;
  aux->sig=NULL;
  if (raiz==NULL) raiz=aux;
  else {
    aux->sig=raiz;
    raiz=aux;
  }
}      

void imprimeLista() {
  NODO *aux;
  
  aux=raiz;
  printf("\nImprime");
  while (aux!=NULL) {
    printf("\nDato: %d", aux->dato);
    aux=aux->sig;
  }
}
void eliminar() {
	int eliminar;
	NODO *auxiliar,*anterior;
	printf("\nQue dato desea eliminar ?");
	scanf("%i",&eliminar);
	printf("\n%i",eliminar);
	auxiliar=raiz;
	anterior=raiz;
	while(auxiliar->sig!=NULL) {
		printf("\nciclo bien");
		if(auxiliar->dato == eliminar){
				printf("\nentre");
				anterior->sig=auxiliar->sig;
				free(auxiliar);
				break;
		}	
		anterior=auxiliar;
		auxiliar=auxiliar->sig;
	}
	if (eliminar==auxiliar->dato){
		
	}
}
void insertar_orden(int nuevo_valor) {
	NODO *auxiliar,*nuevo_nodo,*anterior;
	auxiliar=raiz;
	anterior=raiz;
	nuevo_nodo=(NODO *)malloc(sizeof(NODO));
	nuevo_nodo=raiz;
	if(auxiliar==NULL) {
		auxiliar->dato=nuevo_valor;
		auxiliar->sig=raiz;
	}
	else 
		if(auxiliar->sig==raiz)
			if (auxiliar->dato>nuevo_valor) {
				nuevo_nodo->dato=nuevo_valor;
				nuevo_nodo->sig=auxiliar;
				auxiliar->sig=NULL;
			}
			else {
				nuevo_nodo->dato=nuevo_valor;
				auxiliar->sig=nuevo_nodo;
				nuevo_nodo->sig=NULL;
			}
		else {
			while(auxiliar->sig!=NULL) {
				if (nuevo_valor < auxiliar->dato){
					nuevo_nodo->dato=nuevo_valor;
					anterior->sig=nuevo_nodo;
					nuevo_nodo->sig=auxiliar;
					break;
				}
				anterior=auxiliar;
				auxiliar=auxiliar->sig;
			}
			if (auxiliar->sig==NULL) {
				nuevo_nodo->dato=nuevo_valor;
				auxiliar->sig=nuevo_nodo;
				nuevo_nodo->sig=NULL;
			}
		}
}
void eliminaFinal() {
     NODO *aux;
     NODO *ant;
     
     aux=raiz; 
     ant=raiz;
     if (raiz!= NULL) {  //la lista no esta vacia
       while (aux->sig !=NULL)  {
         ant=aux;     
         aux=aux->sig;
       }       
       if (raiz->sig==NULL) {
         free(aux);    //quiere decir que la lista solo tiene un nodo
         raiz=NULL;
       }
       else {
         free(aux);
         ant->sig=NULL;
       }
     }
}

main() {
	int i,valor;
  raiz=NULL;
	for (i=0;i<=5;i++) {
		printf("\nDame el valor a insertar ");
		scanf("%i",&valor);
		insertar_orden(valor);
	}
	eliminar();
  imprimeLista();
  getchar();
}
Desde ya muchas gracias :D
  #2 (permalink)  
Antiguo 12/04/2010, 19:59
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: ayuda con listas dinamicas en C :)

si haces
Código C++:
Ver original
  1. {
  2.   // ...
  3.           i = 3;
  4.           i = 5;

donde queda el 3? -> se pierde, al haber asignado el 5 a la misma variable.

Por que digo esto?
Pues haces justo eso, aunque no tan evidentemente como aqui expongo, pero casi:

Código C++:
Ver original
  1. {
  2.   // ...
  3.     nuevo_nodo=(NODO *)malloc(sizeof(NODO));
  4.     nuevo_nodo=raiz;
  #3 (permalink)  
Antiguo 12/04/2010, 20:05
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: ayuda con listas dinamicas en C :)

Ademas:

Si tienes un puntero a una estructura

estructura * p;

hacer

p->campo_de_la_estructura

es solo valido si p no es NULL.

Tu codigo dice justo lo contrario

Código C++:
Ver original
  1. if(auxiliar==NULL) {
  2.         auxiliar->dato=nuevo_valor;
  3.         auxiliar->sig=raiz;
  4.     }
  #4 (permalink)  
Antiguo 14/04/2010, 17:37
 
Fecha de Ingreso: marzo-2010
Mensajes: 10
Antigüedad: 14 años, 1 mes
Puntos: 0
Respuesta: ayuda con listas dinamicas en C :)

Ps modifique mi código raramente solo funciono una vez y luego mi viejo amigo segmentation fault salio :D muchas gracias a las respuestas anteriores por cierto me sirvieron para hacerlo un poco mas simple mi código :D.

Código:
#include <stdio.h>
#include <stdlib.h>

typedef struct n{
       int dato;
       struct n *sig;
       }NODO;
 
NODO *raiz;

void insertaInicio(int d) {
  NODO *aux;
  
  aux=(NODO *)malloc(sizeof(NODO));
  aux->dato=d;
  aux->sig=NULL;
  if (raiz==NULL) raiz=aux;
  else {
    aux->sig=raiz;
    raiz=aux;
  }
}      

void imprimeLista() {
  NODO *aux;
  
  aux=raiz;
  printf("\nImprime");
  while (aux!=NULL) {
    printf("\nDato: %d", aux->dato);
    aux=aux->sig;
  }
}
void eliminar() {
	int eliminar;
	NODO *auxiliar,*anterior;
	printf("\nQue dato desea eliminar ?");
	scanf("%i",&eliminar);
	printf("\n%i",eliminar);
	auxiliar=raiz;
	anterior=raiz;
	while(auxiliar->sig!=NULL) {
		printf("\nciclo bien");
		if(auxiliar->dato == eliminar){
				printf("\nentre");
				anterior->sig=auxiliar->sig;
				free(auxiliar);
				break;
		}	
		anterior=auxiliar;
		auxiliar=auxiliar->sig;
	}
	if (eliminar==auxiliar->dato){
		
	}
}
void insertar_orden(int nuevo_valor) {
	NODO *principal,*anterior,*nuevo_nodo;
	nuevo_nodo=(NODO *)malloc(sizeof(NODO));
	anterior=raiz;
	principal=raiz;
	if (principal==NULL) {
		principal->dato=nuevo_valor;
		principal->sig=principal;
	}
	else {
		nuevo_nodo->dato=nuevo_valor;
		while (principal->sig!=NULL)
			if (principal->dato <= nuevo_nodo->dato) {
				anterior=principal;
				principal=principal->sig;
			}
			else {
				anterior->sig=nuevo_nodo;
				nuevo_nodo->sig=principal;
				raiz=nuevo_nodo;
				break;
			}
		}
}
void eliminaFinal() {
     NODO *aux;
     NODO *ant;
     
     aux=raiz; 
     ant=raiz;
     if (raiz!= NULL) {  //la lista no esta vacia
       while (aux->sig !=NULL)  {
         ant=aux;     
         aux=aux->sig;
       }       
       if (raiz->sig==NULL) {
         free(aux);    //quiere decir que la lista solo tiene un nodo
         raiz=NULL;
       }
       else {
         free(aux);
         ant->sig=NULL;
       }
     }
}

main() {
	int i,valor;
	raiz->sig=NULL;
	for (i=0;i<3;i++) {
		printf("\nDame el valor a insertar ");
		scanf("%i",&valor);
		insertar_orden(valor);
	}
	eliminar();
  imprimeLista();
  getchar();
}
  #5 (permalink)  
Antiguo 14/04/2010, 19:29
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: ayuda con listas dinamicas en C :)

la variable "raiz" parte con valor NULL y el main hace
Código C++:
Ver original
  1. raiz->sig = NULL
pareciendo indicar que raiz apunta a algo, cuando no es asi.
raiz es NULL y como dije previamente, p->cualquier_cosa no tiene sentido cuando p es NULL

insertar_orden tiene estas instrucciones ahora:
Código C++:
Ver original
  1. if (principal==NULL) {
  2.         principal->dato=nuevo_valor;
  3.         principal->sig=principal;
  4.     }

o sea, en escencia, lo mismo que antes (desreferenciar un puntero NULL), pero con otra variable.

Segmentation fault es el "castigo" que recibes por desreferenciar punteros NULL.
  #6 (permalink)  
Antiguo 15/04/2010, 16:11
 
Fecha de Ingreso: marzo-2010
Mensajes: 10
Antigüedad: 14 años, 1 mes
Puntos: 0
Respuesta: ayuda con listas dinamicas en C :)

Muchas gacias amigo listo ahora entendí mejor :) ahora me pregunto como podria hacer, el código esta bien pero... me he dado cuenta que en mi funcion insertar_orden inserto los nodos, ahora mi duda seria como evitar que mi nuevo nodo no se perdiera al terminar mi función, porque es lo que pasa al terminar mi función mi nuevo nodo se pierde, mi segmentation fault se libro me podrian volver a ayudar plz.

Código:
#include<stdio.h>
#include<stdlib.h>
typedef struct n{
	int dato;
	struct n *sig;
}NODO;
NODO *raiz;
int inserta_orden(int nv) {
	NODO *principal,*anterior,*nuevo_nodo;
	nuevo_nodo=(NODO *)malloc(sizeof(NODO));
	nuevo_nodo->dato=nv;
	nuevo_nodo->sig=NULL;
	principal=raiz;
	anterior=raiz;
	if (raiz==NULL) {
		raiz=nuevo_nodo;
		return 0;
	}
	else {
		if (anterior==principal)
			if (nuevo_nodo->dato < principal->dato) {
				nuevo_nodo->sig=principal;
				principal->sig=NULL;
				return 0;
			}
		    else {
				principal->sig=nuevo_nodo;
				return 0;
			}
		while (principal!=NULL && principal->dato < nuevo_nodo->dato) {
			anterior=principal;
			principal=principal->sig;
		}
			if (principal->sig!=NULL) {
				anterior->sig=nuevo_nodo;
				nuevo_nodo->sig=principal;
			}
		    else
				principal->sig=nuevo_nodo;
	}
}
void imprimir() {
	NODO *aux;
	aux=raiz;
	printf("\nImprime:");
	while (aux->sig!=NULL) {
		printf("\n%i",aux->dato);
		aux=aux->sig;
	}
}
main () {
	int i,num;
	raiz=NULL;
	for (i=0;i<3;i++) {
		printf("\nDame un numero ");
		scanf("%i",&num);
		inserta_orden(num);
	}
	imprimir();
	return 0;
}
Desde ya muchas gracias :D
  #7 (permalink)  
Antiguo 18/04/2010, 13:16
 
Fecha de Ingreso: marzo-2010
Mensajes: 10
Antigüedad: 14 años, 1 mes
Puntos: 0
Respuesta: ayuda con listas dinamicas en C :)

:O listo solucionado a todos los que me ayudaron mil gracias :D se me hizo complicado entender listas ligadas pero si no sé lucha y busca jamás le entenderia grax por no darme la respuesta directa y muchisimas gracias CalgaryCorpus :)
  #8 (permalink)  
Antiguo 18/04/2010, 13:45
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: ayuda con listas dinamicas en C :)

Seria valioso tambien ver el resultado final (como quedo el codigo fuente al final).
  #9 (permalink)  
Antiguo 21/04/2010, 16:43
 
Fecha de Ingreso: marzo-2010
Mensajes: 10
Antigüedad: 14 años, 1 mes
Puntos: 0
Respuesta: ayuda con listas dinamicas en C :)

bueno supongo que no es elcódigo más optimo pero para empezar creo que esta bn

Código:
#include<stdio.h>
#include<stdlib.h>
typedef struct n{
	int dato;
	struct n *sig;
}NODO;
NODO *raiz;
int inserta_orden(int nv) {
	NODO *principal,*anterior,*nuevo_nodo;
	nuevo_nodo=(NODO*)malloc(sizeof(NODO));
	nuevo_nodo->dato=nv;
	nuevo_nodo->sig=NULL;
	principal=raiz;
	anterior=raiz;
	if (raiz==NULL) {
		raiz=nuevo_nodo;
		return 0;
	}
		if (nuevo_nodo->dato < principal->dato) {
			raiz=nuevo_nodo;
			raiz->sig=principal;
			return 0;
		}
		while (principal->dato < nuevo_nodo->dato) {
			if (principal->sig==NULL)
				break;	
				anterior=principal;
				principal=principal->sig;
			}
			if (principal->sig!=NULL) {
				anterior->sig=nuevo_nodo;
				nuevo_nodo->sig=principal;
			}
		    else
				principal->sig=nuevo_nodo;
}
void imprimir(int num) {
	NODO *aux;
	int i;
	aux=raiz;
	printf("\nImprime:");
	for(i=0;i<num;i++) {
		printf("\n%i",aux->dato);
		aux=aux->sig;
	}
}
int eliminar(int del) {
	NODO *principal,*anterior;
	if (raiz==NULL) {
		printf("\nTu lista esta vacia");
		return 0;
	}
	principal=raiz;
	anterior=raiz;
	if (principal->sig==NULL && principal->dato==del) {
		free(principal);
		raiz=NULL;
	}
	else {
		while (principal->dato!=del&&principal->sig!=NULL) {
			anterior=principal;
			principal=principal->sig;
		}
		if (principal->dato==del) 
			if(principal->sig==NULL) {
				anterior->sig=NULL;
				free(principal);
			}
			else if(principal==raiz)
				free(principal);
			else {
				anterior->sig=principal->sig;
				free(principal);
			}
		else
			printf("\nDato no encontrado");
	}
}
main () {
	int i,num,veces,borrar;
	raiz=NULL;
	printf("\nCuantos números deseas leer? ");
	scanf("%i",&veces);
	for(i=0;i<veces;i++) {
		printf("\nDame un numero ");
		scanf("%i",&num);
		inserta_orden(num);
	}
	imprimir(num);
	return 0;
}
Por cierto mi fúncion eliminar no funciono :S jahajajaja sali de un problema para entrar en otro me podrian ayudar o decirme si tengo algún error plz :)

Etiquetas: dinamicas, listas
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 09:19.