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

int main()
{
    struct complejos{ //Se define la estructura.
        double re;
        double im;
        struct complejos *sig; //Puntero a la estructura.
        struct complejos *ant;
    }*lista=NULL, *rec=NULL, *nodo=NULL, *fin=NULL;

    char opcion;
    while(1)
    {
        system("cls"); //Limpia pantalla.
        printf("1.- Agregar Complejo\n"
               "2.- Mostrar Complejos\n"
               "3.- Recorrer Lista Invertida\n"
               "4.- Salir\n"); //Muestra Menú
        while(opcion=getch(), opcion<'1'||opcion>'4');//Espera a que se teclee entre 1 y 3
        switch(opcion)
        {
            case '1':
            {
                nodo=(struct complejos*)malloc(sizeof(struct complejos)); //Se crea nodo.
                if(!nodo) //hay memoria disponible?
                {
                    printf("No hay memoria disponible.\n");
                    break;
                }
                printf("Ingrese parte real: "); //Se ingresan datos.
                scanf("%lf", &nodo->re);
                printf("Ingrese parte imaginaria: ");
                scanf("%lf", &nodo->im);
                nodo->sig=NULL;  //Como se agrega nodo al final de la lista, siempre el elemento siguiente del nuevo nodo apunta a NULL
                nodo->ant=NULL; //Puntero al elemento anterior de la lista.
                if(!lista) //Si no hay lista se crea.
                {
                    lista=nodo; //Siempre la primera dirección de la lista se debe tener, pues sino no se tendría acceso a estos elementos
                    fin=nodo;
                }
                else{
                    rec=fin; //Si hay lista, rec apunta al final de esta
                    fin->sig=nodo; //se agrega nodo al final.
                    nodo->ant=rec; //La posicion anterior al nodo es la que apunta rec.
                    fin=nodo; //El ultimo elemento es el nodo agregado, por lo tanto fin apunta al nodo nuevo.
                }

            }break;
            case '2':
            {
                if(!lista) //Tiene que haber lista para mostrarse
                {
                    printf("No hay lista.\n");
                    break;
                }
                rec=lista; //Se hace apuntar rec al primer elemento de la lista.
                while(rec) //Mientras hayan datos que mostrar se imprimen en pantalla.
                {
                    printf("%lf + i %lf\n", rec->re, rec->im);
                    rec=rec->sig;
                }
            }break;
            case '3':
            {
                if(!lista)
                {
                    printf("No hay lista.\n");
                    break;
                }
                rec=fin; //Rec apunta al final de la lista.
                while(rec)
                {
                    printf("%lf + i %lf\n", rec->re, rec->im);
                    rec=rec->ant;
                }
            }break;
            case '4':
            {
                if(lista)
                    do{
                        rec=lista->sig; //Se hace apuntar rec al valor siguiente de la lista
                        free(lista); //Se libera la memoria del nodo
                        lista=rec; //Ahora lista apunta al valor apuntado por rec
                    }while(rec); //Si se finaliza de usar la memoria, se debe liberar

                system("pause");
                return 0; //Se termina el programa.
            }
        }
        system("pause");
    }
}
