Invertir una Lista en C - La funcion Pop no me da el ultimo elemento.?

Iniciado por palacio29, 26 Octubre 2016, 01:09 AM

0 Miembros y 1 Visitante están viendo este tema.

palacio29

Hola

Estoy haciendo un programa en el cual tengo que agregar elementos a una lista, luego imprimir la lista y luego crear otra lista en el cual se rellene con los valores de la lista anterior de manera invertida.
El ejercicio parece simple. El problema es que yo uso la funcion pop, que tengo entendido que retorna el ultimo valor de la lista y no me esta retornando el ultimo elemento, sino que primero retorna el primero, luego el segundo y asi...
Dejo mi codigo, supongo que sera algo muy facil pero no le encuentro el defecto a las funciones que programe.

/*Ejercicio 5.6
Programar una función que invierta una lista de enteros. Considere que la lista puede estar vacía*/

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

struct s_nodo
{
    int valor;
    struct s_nodo*sig;
};
typedef struct s_nodo *t_nodo;

void agregar(t_nodo*,int);
void imprimirLista(t_nodo);
void invertirLista(t_nodo*,t_nodo*);
int pop(t_nodo*);

int main()
{
    t_nodo lista=NULL;
    t_nodo inversa=NULL;
    agregar(&lista,1);
    agregar(&lista,3);
    agregar(&lista,5);
    agregar(&lista,7);
    printf("\nLista impresa = ");
    imprimirLista(lista);
    invertirLista(&lista,&inversa);
    printf("\nLista inversa = ");
    imprimirLista(inversa);
    return 0;
}

void agregar(t_nodo* nodo,int valor)
{
    if(*nodo==NULL)
    {
        *nodo=(t_nodo)malloc(sizeof(struct s_nodo));
        if(*nodo==NULL)
            return;
        (*nodo)->valor=valor;
        (*nodo)->sig=NULL;
    }
    else
        agregar(&((*nodo)->sig),valor);
}

void imprimirLista(t_nodo lista)
{
    while(lista!=NULL)
    {
        printf(" %d  ",lista->valor);
        lista=lista->sig;
    }
}

void invertirLista(t_nodo *lista,t_nodo* inversa)
{
    int valor;
    while(*lista!=NULL)
    {
        valor=pop(lista);
        agregar(inversa,valor);
    }
}

int pop(t_nodo* nodo)
{
    t_nodo aux=*nodo;
    int valor=aux->valor;
    *nodo=aux->sig;
    free(aux);
    return valor;
}

MAFUS

El problema es que tu lista crece por el final pero quitas por el principio.

palacio29

Cita de: MAFUS en 26 Octubre 2016, 19:44 PM
El problema es que tu lista crece por el final pero quitas por el principio.

Y como puedo hacer que el POP tome el ultimo elemento?

Si mi lista es 3 - 5 -7 -9

Yo quiero sacar el 9, luego el 7, luego el 5 y asi sucesivamente pero nose como empezar desde  el final e ir para el principio, solo se ir desde el comienzo hasta el final.

MAFUS

Tendrías que mirar si (*nodo)->sig->sig vale NULL para sacar el valor de (*nodo)->sig->valor. Después hacer un free sobre (*nodo)->sig para terminar llevando a NULL (*nodo)->sig. Como puedes ver es muy complicado.

Te sería mucho más fácil cambiar la función agregar para hacer de tu lista una pila. El último objeto que entres debe estar en cabeza. Tu función pop quedaría tal y como la tienes. Para tu función agregar (por conveniencia sería mejor que la llamaras push):
La función debe recibir un puntero a la lista y el valor a añadir.
Dentro: creas una variable auxiliar de tipo nodo. Como valor le das el valor que te han pasado a la función. Como siguiente elemento apuntas a la lista.
Haces que la raíz de la lista que te han pasado como argumento apunte al nodo auxiliar.
Listo, ya tienes tu programa funcional.