listas simplemente enlazadas

Iniciado por m@o_614, 29 Mayo 2012, 18:49 PM

0 Miembros y 2 Visitantes están viendo este tema.

m@o_614

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;
}

durasno

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
Ahorrate una pregunta, lee el man

m@o_614

#2
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

durasno

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
Ahorrate una pregunta, lee el man

0xDani

Espera, L * ultimo. Un puntero a L?Que tipo es ese? Que alguien me lo explique, por favor.

Saludos ;D
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

Ferno

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".

0xDani

I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

m@o_614

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

durasno

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
Ahorrate una pregunta, lee el man

m@o_614

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