Saludos estoy haciendo el siguiente codigo de listas enlazadas que me ingresen datos por el final de la lista, todavia me cuesta trabajo comprender esto de las listas y es por eso que solamente tengo una funcion de los cases hecha, pero me marca errores como:
dereferencing pointer to incomplete type y no entiendo que es lo que estoy haciendo mal
#include <stdio.h>
#include <stdlib.h>
typedef struct info
{
int dato;
struct lista *sig;
}L;
void insertar_final(int x,L *lista);
int main()
{
L *lista;//Aqui coloco el puntero hacia la estructura
lista= NULL;//Lo inicializo en NULL para indicar que esta vacia
int opcion,continuar=1,x;
do
{
printf("Menu!\n");
printf("1) Insertar al final\n");
printf("2) Mostrar lista\n");
printf("3) Buscar elemento\n");
printf("4) Busqueda recursiva\n");
printf("5) Contar elementos en la lista\n");
printf("6) Salir\n");
scanf("%d",&opcion);
switch(opcion)
{
case 1:
printf("Dame el dato que deseas insertar:\n");
scanf("%d",&x);
insertar_final(x,lista);//le paso el dato que deseo colocar como primer nodo y el puntero
break;
case 2:
//no lo he terminado
break;
case 3:
//no lo he terminado
break;
case 4:break;
//no lo he terminado
case 5:break;
//no lo he terminado
case 6:
continuar=0;
break;
default:
printf("Opcion no valida\n");
}
}while(continuar);
return 0;
}
void insertar_final(int x,L *lista)
{
L *ultimo;//otro puntero ahora hacia el ultimo nodo
ultimo->sig=(L*)malloc(sizeof(L));//le asigno memoria (creo nuevo nodo)
ultimo->sig->dato= x;//le asigno el elemento que queria
ultimo->sig->sig=NULL;
ultimo= ultimo->sig;
}
Hola! el problema es q vos declaras un puntero "ultimo" pero no le reservas memoria, lo que estas haciendo es reservar memoria al siguiente de ultimo lo cual esta mal. Una pregunta ¿¿para que intentas reservar al siguiente?? no es mejor hacer:
void insertar_final(int x,L *lista)
{
L *ultimo;//otro puntero ahora hacia el ultimo nodo
ultimo=(L*)malloc(sizeof(L));//le asigno memoria (creo nuevo nodo)
ultimo->dato= x;//le asigno el elemento que queria
ultimo->sig=NULL;
}
De todas formas el error principal es q no estas enlazando la lista. Una forma de resolver es hacer:
case 1:
printf("Dame el dato que deseas insertar:\n");
scanf("%d",&x);
lista=insertar_final(x,lista);
breaK;
...................
struct info * insertar_final(int x,L *lista)
{
L *ultimo;//otro puntero ahora hacia el ultimo nodo
ultimo=(L*)malloc(sizeof(L));//le asigno memoria (creo nuevo nodo)
ultimo->dato= x;//le asigno el elemento que queria
ultimo->sig=NULL;
if(lista==NULL) /* si la lista esta vacia */
return ultimo;
else {
while(lista->sig!=NULL) /* busco el ultimo nodo */
lista=lista->sig; /* cambio al siguiente nodo */
lista->sig=ultimo; /* el ultimo de la lista apunta al "ultimo" creado en esta funcion */
}
}
Solo es necesario retornar "ultimo" cuando la lista esta vacia. En el bucle lo que hice es buscar el ultimo nodo y enlazarlo al puntero "ultimo". No lo compile pero deberia funcionar
Saludos
Saludos durasno respondiendo a tu pregunta lo que pasa es que como ultimo ya lo habia declarado como apuntador pensé que reservandole memoria en
ultimo->sig
lo que estaba haciendo era creando un nuevo nodo que estuviera enlazado al campo sig del apuntador ultimo, no se si me di a entender??? :-\ o sea que crei que ultimo al momento de declararlo como apuntador era un nodo que tenia un campo dato y un enlace sig, pense que con tan solo hacer esto:
L *ultimo;
ya tenia la direccion de una estructura
entendi bien?? No se si este es mi principal error
saludos y gracias
Como vos decis
Citareste es mi principal error
Declarar un puntero a la estructura no implica que ya puedas hacer uso de los campos de la struct, siempre a un puntero le tenes q asignar algo. En otras palabras un puntero no es mas que una variable, y como toda variable(int, float....) le tenes q asignar algo. Lo q vos hiciste equivale a hacer:
int a,c;
int b=10;
c=b + a; // y esto q da como resultado????
Espero se haya entendido. Saludos
Espera, L * ultimo. Un puntero a L?Que tipo es ese? Que alguien me lo explique, por favor.
Saludos ;D
Cita de: daniyo en 1 Junio 2012, 16:07 PM
Espera, L * ultimo. Un puntero a L?Que tipo es ese? Que alguien me lo explique, por favor.
Saludos ;D
Fijate que la declaración del struct es de esta manera:
typedef struct info
{
int dato;
struct lista *sig;
}L;
Luego de cerrar con llaves, existe la posibilidad (porque si quieres lo puedes omitir) de escribirle un nombre al tipo que definiste para reconocerlo fácilmente (puesto que es un nombre que escribiste vos) y no tener que escribir "struct info" cada vez que quieres utilizar el tipo en alguna declaración.
En este código, "L" hace referencia al tipo "struct info".
Ah Ok, no lo habia visto.
Aqui ya dividi la tarea de agregar nodos con las funciones insertar_final y nuevo_nodo (es la que crea el nodo) pero todavia no me queda claro para que utilizar el apuntador lista, si fuera una lista que inserte por el encabezado sería un poco más fácil, pero como en insertar al final no tengo un puntero que me apunte al ultimo nodo y tengo que recorrer la lista y despues insertar
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
typedef struct info
{
int dato;
struct info *sig;
}L;
void insertar_final(int i,L **lista);
L *nuevo_nodo(int i);
int main()
{
L *lista;
lista= NULL;//inicializo la lista vacia
srand(time(NULL));
int opcion,continuar=1,i;
do
{
printf("Menu!\n");
printf("1) Insertar al final\n");
printf("2) Mostrar lista\n");
printf("3) Buscar elemento\n");
printf("4) Busqueda recursiva\n");
printf("5) Contar elementos en la lista\n");
printf("6) Salir\n");
scanf("%d",&opcion);
switch(opcion)
{
case 1:
for(i=(rand()%MAX+1);i;)
insertar_final(i,&lista);
break;
case 2:
break;
case 3:
//no lo he terminado
break;
case 4:break;
//no lo he terminado
case 5:break;
//no lo he terminado
case 6:
continuar=0;
break;
default:
printf("Opcion no valida\n");
}
}while(continuar);
return 0;
}
void insertar_final(int i,L **lista)
{
L *ultimo;
ultimo= nuevo_nodo(i);
if(ultimo->sig!=NULL)//aqui recorro la lista hasta encontrar NULL
ultimo=ultimo->sig;
ultimo->sig= *lista;//aqui ya encontro NULL entonces lo apunto con lista
}
L *nuevo_nodo(int i)
{
L *nuevo;
nuevo= (L*)malloc(sizeof(L));
nuevo->dato= i;
nuevo->sig= NULL;
return nuevo;
}
saludos
Hola! tal vez si te hicieras algunos graficos entenderias un poco mejor... Con esto: if(ultimo->sig!=NULL)//aqui recorro la lista hasta encontrar NULL
ultimo=ultimo->sig;
no estas recorriendo la lista, es con while. Igual esta mal vos no podes recorrer la lista con el puntero ultimo(ultimo no es la lista); la lista es el puntero "lista"
Y con esto:ultimo->sig= *lista;//aqui ya encontro NULL entonces lo apunto con lista
no estas haciendo que ultimo se coleque al final de la lista sino al principio; igual la logica tambien esta mal
Fijate el codigo q te pase antes, si bien no use puntero a puntero, lo podes hacer vos solo cambiando algunas cosas
Saludos
Saludos
aqui ya el código no me marca errores ni me saca del programa como antes, pero no hace nada. Si te fijas es casi el mismo código que el tuyo
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
typedef struct info
{
int dato;
struct info *sig;
}L;
void insertar_final(int i,L *lista);
L *nuevo_nodo(int i);
int main()
{
L *lista;
lista= NULL;//inicializo la lista vacia
srand(time(NULL));
int opcion,continuar=1,i;
do
{
printf("Menu!\n");
printf("1) Insertar al final\n");
printf("2) Mostrar lista\n");
printf("3) Buscar elemento\n");
printf("4) Busqueda recursiva\n");
printf("5) Contar elementos en la lista\n");
printf("6) Salir\n");
scanf("%d",&opcion);
switch(opcion)
{
case 1:
for(i=(rand()%MAX+1);i;)
insertar_final(i,lista);
break;
case 2:
break;
case 3:
//no lo he terminado
break;
case 4:break;
//no lo he terminado
case 5:break;
//no lo he terminado
case 6:
continuar=0;
break;
default:
printf("Opcion no valida\n");
}
}while(continuar);
return 0;
}
void insertar_final(int i,L *lista)
{
L *ultimo;
ultimo= nuevo_nodo(i);
if(lista==NULL)
lista=ultimo;
while(lista->sig!=NULL)
lista=lista->sig;
lista->sig=ultimo;
}
L *nuevo_nodo(int i)
{
L *nuevo;
nuevo= (L*)malloc(sizeof(L));
nuevo->dato= i;
nuevo->sig= NULL;
return nuevo;
}
gracias
Vos mismo lo dijiste es casi igual, pero no lo es... Fijate en el if de insertar_final() pregunto si lista es NULL(lista vacia), si es verdadero retorno la estructura creada. (ademas t falta un else :P)
Si vos pasas de esta manera el puntero:
insertar_final(i,lista); // llamada a la funcion
cuando lista regrese al main no va a hacer ningun cambio, esto es porque el puntero se paso por valor. Podes hacer dos cosas: retornar una estructura como lo hic antes o pasar el puntero por referencia, ¿como? pasando la direccion del puntero
insertar_final(i,&lista); // paso la direccion
......................
void insertar_final(int i,L **lista)
{
L *ultimo;
ultimo= nuevo_nodo(i);
if(*lista==NULL) /* lista vacia */
*lista=ultimo;
else {
L *aux=*lista; /* creo un puntero auxiliar para q me recorra la lista */
while(aux->sig!=NULL) /* recorro la lista */
aux=aux->sig; /* cambia al siguiente nodo */
aux->sig=ultimo; /* el ultimo de la lista apunta a "ultimo" creado aca
}
}
Fijate que creo un puntero auxiliar para recorrer la lista; esto es porque si vos usas el puntero lista vas a perder la referencia al primer nodo lo cual no es bueno... Cualquier duda segui pregutando
Saludos