Glaas2

Listas Dobles con Funciones

Jul 14th, 2018
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.03 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <stdlib.h>
  3.  
  4. /***************************** PARTE SOLO PARA LAS FICHAS QUE SE METERÁN EN LA LISTA *****************fichas.h*****************/
  5. #define TAM_NOMBRE 50
  6. typedef struct datos_de_ficha       // Renombra el tipo de dato compuesto "struct datos_de_ficha" a "FICHA"
  7. {                                   // FICHA es un tipo de dato ahora, como int, float o char
  8.     int edad;                       // se usará para declarar variables de tipo compuesto FICHA
  9.     float peso;
  10.     char nombre[TAM_NOMBRE];
  11. }FICHA;
  12.  
  13. void llenar_ficha(FICHA *n_ficha)   // Llena los datos de la ficha, recibe un apuntador a la dirección de la variable
  14. {
  15.     int i;
  16.  
  17.     n_ficha->edad = rand() % 101;   // Como es un apuntador, se usa el operador flecha -> para acceder a un dato
  18.     n_ficha->peso = rand() % 300;
  19.  
  20.     for (i = 0; i < rand() % TAM_NOMBRE - 1; i++)   // Si i es menor a un numero aleatorio menor que TAM_NOMBRE-1
  21.         n_ficha->nombre[i] = 'a' + rand() % ('z' - 'a' + 1);    // Llena caracter por caracter de un rango de a hasta z
  22.     n_ficha->nombre[i] = '\0';  //i termina con el valor aleatorio máximo y en esa ultima posición pone fin a la cadena
  23. }
  24.  
  25. void imprimir_ficha(FICHA ficha)
  26. {
  27.     puts("Datos de la ficha");
  28.     printf("NOMBRE: \t"); puts(ficha.nombre);
  29.     printf("EDAD:   \t%d \n", ficha.edad);
  30.     printf("PESO:   \t%.2f \n\n", ficha.peso);
  31. }
  32.  
  33. /******************************** PARTE SOLO PARA LISTA  Y SUS FUNCIONES **********************************lista.h*************/
  34.  
  35. //listas.h
  36. /* CODIGOS DE ERROR
  37. *   -1 : No se pudo obtener la memoria para crear un nuevo nodo
  38. *   -2 : Posición inválida, la posición dada es menor que cero o mayor que el tamaño de la lista
  39. *   -3 : Posiciones iguales, no se puede hacer intercambio de nodos con la misma posición
  40. *   -4 : La lista no se elimina porque está vacía o no existe
  41. *   -5 : Error: opción no válida, al seleccionar comparación
  42. **/
  43. //#pragma once
  44. //#include "fichas.h"
  45.  
  46.  
  47.  
  48. typedef struct elemento_de_lista        // Declara un tipo de dato compuesto para que sea un elemento de una lista
  49. {                                   // y lo renombra como NODO
  50.     FICHA datos;        // Es una variable de tipo FICHA, por lo que puede guardar edad, peso, etc.
  51.     elemento_de_lista *ANT, *SIG;   // Son apuntadores al tipo de dato NODO, por lo que pueden guardar la
  52.     int pos;                                // dirección de un NODO de la lista, en este caso el NODO anterior y siguiente.
  53. }NODO;
  54.  
  55. struct LISTA {      // Esta estructura que llamaremos LISTA apuntará a 2 direcciones de variables NODO
  56.     NODO *inicio;   // para poder tener mas control y saber donde empieza o acaba la lista así como su tamaño
  57.     NODO *fin;
  58.     int tam;
  59. };
  60.  
  61. void inicializar_lista(LISTA *lista)        // Función para preparar la lista antes de usarla
  62. {
  63.     lista->tam = 0; // Indica que la lista no tiene elementos
  64.     lista->inicio = NULL;   // Como no tiene elementos no tiene inicio ni fin, ambos son nulos
  65.     lista->fin = NULL;
  66.  
  67. }
  68.  
  69. NODO* crear_nodo()      // Función que genera un elemento de lista que se unirá después
  70. {
  71.     /* Declara una variable que apunta a un tipo NODO, como no sabemos que tamaño tendrá "pide" -malloc()- espacio    *
  72.      * y el tamaño que pide es el que ocupa una variable NODO -sizeof(NODO)- y ese espacio que se asigna se            *
  73.      * convierte en espacio para variables del tipo apuntador a NODO -(NODO*)-                                      */
  74.     NODO *nuevo_nodo = (NODO*)malloc(sizeof(NODO));
  75.     FICHA nueva_ficha;      // Genera una variable tipo ficha
  76.  
  77.     llenar_ficha(&nueva_ficha); // llenamos los datos de la ficha
  78.     nuevo_nodo->datos = nueva_ficha;        // copiamos los datos de la variable al elemento de la lista que creamos
  79.     return nuevo_nodo;  // regresa la dirección del elemento de la lista, para poder manipularlo después
  80. }
  81.  
  82. /* Esta función enumera cada elemento de la lista, desde 1 hasta el tamaño actual de la lista (lista->tam)        */
  83. void asignar_pos(LISTA *lista)
  84. {
  85.     NODO *nodo = crear_nodo();  // creamos un apuntador a NODO, que nos ayudará a recorrer la lista
  86.     int i = 1;
  87.     nodo = lista->inicio;   // apuntamos el nodo al primer elemento de la lista para recorrerla
  88.  
  89.     /*recorre la lista hasta el ultimo elemento (que es el que su SIG apunta a NULL)*/
  90.     while (nodo != NULL)
  91.     {
  92.         nodo->pos = i;  // asigna el valor de posición, desde 1
  93.         nodo = nodo->SIG;
  94.         i++;
  95.     }
  96. }
  97.  
  98. int insertar_en_lista_vacia(LISTA *lista)
  99. {
  100.     NODO *nuevo_nodo;
  101.     nuevo_nodo = crear_nodo(); // creamos un nuevo nodo, con los datos ya guardados
  102.     if (nuevo_nodo == NULL) // si al crear el nodo, este vale NULL significa que hubo un error y no pudo
  103.         return -1;          // obtener la memoria que "pidió"
  104.  
  105.     nuevo_nodo->SIG = NULL; // como será el unico elemento en la lista, no apunta a ningun elemento antes o después
  106.     nuevo_nodo->ANT = NULL;
  107.     nuevo_nodo->pos = 1;
  108.  
  109.     lista->inicio = nuevo_nodo; // decimos que la lista empieza con el nuevo_nodo y termina en nuevo_nodo
  110.     lista->fin = nuevo_nodo;        // es decir, solo tiene un elemento. Aumentamos el tamaño de la lista
  111.     lista->tam++;
  112.  
  113.     return 0;
  114. }
  115.  
  116. int insertar_inicio(LISTA *lista)   // caso donde agregamos un elemento al inicio de la lista
  117. {
  118.     NODO *nuevo_nodo;
  119.     int i = 1;
  120.     nuevo_nodo = crear_nodo();
  121.     if (nuevo_nodo == NULL)
  122.         return -1;
  123.  
  124.     /* Como este nuevo nodo estará al principio, no apuntará a ninguno anterior pero si apuntará a uno siguiente.    *
  125.      * El elemento que le siguie al nuevo nodo es el que antes estaba al principio, por eso nuevo->SIG=lista->inicio */
  126.     nuevo_nodo->ANT = NULL;
  127.     nuevo_nodo->SIG = lista->inicio;
  128.  
  129.     /* El que antes estaba al inicio (lista->inicio) ahora tiene un elemento antes de el, que es el nuevo nodo,  *
  130.      * entonces decimos que el que antes estaba al inicio apunte al nuevo nodo*/
  131.     lista->inicio->ANT = nuevo_nodo;
  132.  
  133.     lista->inicio = nuevo_nodo; // El que está al inicio ahora es el nuevo nodo y el tamaño de la lista aumenta en 1
  134.     lista->tam++;
  135.  
  136.     asignar_pos(lista); // se le asigna una posición a cada elemento de la lista
  137.     return 0;
  138. }
  139.  
  140. int insertar_final(LISTA *lista)
  141. {
  142.     NODO *nuevo_nodo;
  143.     int i = 1;
  144.  
  145.     nuevo_nodo = crear_nodo();
  146.     if (nuevo_nodo == NULL)
  147.         return -1;
  148.  
  149.     /* En el caso de insertar al final, el nuevo nodo será el ultimo elemento en la lista, entonces no apuntará  *
  150.      * a ningun elemento siguiente*/
  151.     nuevo_nodo->SIG = NULL;
  152.     nuevo_nodo->ANT = lista->fin; // el nuevo nodo tiene ahora uno antes, que es el que antes estaba al final
  153.     lista->fin->SIG = nuevo_nodo; // El elemento que estaba antes al final ahora tiene un elemento después
  154.  
  155.  
  156.  
  157.     lista->fin = nuevo_nodo; // decimos que ahora el ultimo elemento es el nuevo nodo y aumentamos el tamaño de la lista
  158.     lista->tam++;
  159.  
  160.     asignar_pos(lista); // numeramos los elementos
  161.  
  162.     return 0;
  163. }
  164.  
  165. int insertar_en_posicion(LISTA *lista, int pos) // Inserta un elemento en la posición que se le pida
  166. {
  167.     if (pos < 1 || pos > lista->tam + 1)
  168.         return -2;//inserta siempre y cuando la posición sea mayor que 0 y menor que el tamaño de la lista
  169.     if (pos == 1) // si la posición pedida es 1, significa que inserta al inicio
  170.     {
  171.         insertar_inicio(lista);
  172.         return 0;
  173.     }
  174.     if (pos == lista->tam + 1) // si la posición es el tamaño de la lista + 1 significia que inserta al final
  175.     {
  176.         insertar_final(lista);
  177.         return 0;
  178.     }
  179.  
  180.     NODO *nuevo, *otro;     // crea un nuevo nodo para insertar y otro para recorrer la lista
  181.  
  182.     nuevo = crear_nodo();
  183.     if (nuevo == NULL)
  184.         return -1;
  185.  
  186.     otro = lista->inicio;   // el otro apunta al inicio y recorre la lista hasta la posición deseada
  187.     while (otro->pos != pos)
  188.         otro = otro->SIG;
  189.  
  190.     /* Ya teniendo la posición donde se insertará, el nuevo nodo apuntará a donde antes apuntaba el otro nodo *
  191.      * ya que este nuevo ocupara su lugar */
  192.     nuevo->ANT = otro->ANT;
  193.     nuevo->SIG = otro;
  194.     otro->ANT->SIG = nuevo; // aqui se le dice al elemento anterior al otro, que ahora tiene un nodo al frente
  195.     otro->ANT = nuevo;      // ese nodo es el nuevo, luego le dice al otro nodo que el que esta antes de el es
  196.     lista->tam++;           // el nuevo nodo. la lista aumenta de tamaño
  197.  
  198.     asignar_pos(lista);
  199.  
  200.  
  201.  
  202.     return 0;
  203. }
  204.  
  205. int eliminar_nodo(LISTA *lista, int pos)
  206. {
  207.     NODO *byebye;
  208.     if (pos <1 || pos > lista->tam)
  209.         return -2;
  210.  
  211.     byebye = lista->inicio;
  212.     if (lista->tam == 1)
  213.     {
  214.         inicializar_lista(lista);
  215.         free(byebye);
  216.         return 0;
  217.     }
  218.     while (byebye->pos != pos)
  219.         byebye = byebye->SIG;
  220.  
  221.     if (pos == 1)
  222.     {
  223.         lista->inicio = byebye->SIG;
  224.         byebye->SIG->ANT = NULL;
  225.     }
  226.  
  227.     else if (pos == lista->tam)
  228.     {
  229.         lista->fin = byebye->ANT;
  230.         byebye->ANT->SIG = NULL;
  231.     }
  232.  
  233.     else
  234.     {
  235.         byebye->ANT->SIG = byebye->SIG;
  236.         byebye->SIG->ANT = byebye->ANT;
  237.     }
  238.     //free(&byebye->datos);
  239.     free(byebye);
  240.     lista->tam--;
  241.     asignar_pos(lista);
  242.  
  243.     return 0;
  244. }
  245.  
  246. int intercambio(LISTA *lista, int pos1, int pos2)
  247. {
  248.     NODO *a, *b;
  249.     int x = 0;
  250.  
  251.     if (pos1 == pos2)
  252.         return -3;
  253.     else if (pos1<1 || pos2<1 || pos1>lista->tam || pos2>lista->tam)
  254.         return -2;
  255.  
  256.     else if (pos1 > pos2)
  257.     {
  258.         x = pos1;
  259.         pos1 = pos2;
  260.         pos2 = x;
  261.     }
  262.  
  263.     a = lista->inicio;
  264.     b = lista->inicio;
  265.     while (a->pos != pos1)
  266.         a = a->SIG;
  267.     while (b->pos != pos2)
  268.         b = b->SIG;
  269.  
  270.     if (pos1 == 1)
  271.     {
  272.         b->ANT = NULL;
  273.         a->ANT = b;
  274.         a->SIG = b->SIG;
  275.         b->SIG->ANT = a;
  276.         b->SIG = a;
  277.         lista->inicio = b;
  278.     }
  279.  
  280.     else if (pos2 == lista->tam)
  281.     {
  282.         b->ANT = a->ANT;
  283.         a->ANT = b;
  284.         a->SIG = NULL;
  285.         b->ANT->SIG = b;
  286.         b->SIG = a;
  287.         lista->fin = a;
  288.     }
  289.  
  290.     else
  291.     {
  292.         b->ANT = a->ANT;
  293.         a->ANT = b;
  294.         a->SIG = b->SIG;
  295.         b->SIG->ANT = a;
  296.         b->SIG = a;
  297.         b->ANT->SIG = b;
  298.     }
  299.     asignar_pos(lista);
  300.     return 0;
  301. }
  302. void imprimir_lista(LISTA *lista)
  303. {
  304.     NODO *actual = lista->inicio; // crea un nodo que recorrerá la lista, comienza desde el inicio de la lista
  305.     while (actual != NULL)
  306.     {
  307.         printf("FICHA # %d\n", actual->pos);
  308.         imprimir_ficha(actual->datos);
  309.         actual = actual->SIG;
  310.     }
  311. }
  312.  
  313. int comparar_dato(int opc, FICHA *ficha1, FICHA *ficha2)
  314. {
  315.     switch (opc)
  316.     {
  317.     case 1: // Comparar edad
  318.         if (ficha1->edad > ficha2->edad)
  319.             return 1;
  320.         else if (ficha1->edad < ficha2->edad)
  321.             return -1;
  322.         else return 0;
  323.         break;
  324.     case 2: // Comparar peso
  325.         if (ficha1->peso > ficha2->peso)
  326.             return 1;
  327.         else if (ficha1->peso < ficha2->peso)
  328.             return -1;
  329.         else return 0;
  330.         break;
  331.     case 3: // Comparar nombre
  332.     {
  333.         char *pcad1 = ficha1->nombre, *pcad2 = ficha2->nombre;
  334.         while (*pcad1 != '\0' && *pcad2 != '\0')
  335.         {
  336.             if (*pcad1 < *pcad2)return -1;
  337.             if (*pcad1 > *pcad2)return  1;
  338.             pcad1++; pcad2++;
  339.         }
  340.         if (*pcad1 < *pcad2)return -1;
  341.         if (*pcad1 > *pcad2)return  1;
  342.         return 0;
  343.     break;
  344.     }
  345.     default:
  346.         return -5; // Error: opción no válida para comparar
  347.         break;
  348. }
  349. }
  350.  
  351. int ordenar_lista_nombre(LISTA *lista)
  352. {
  353.     bool desorden = false;
  354.     NODO *nodo;
  355.  
  356.     do
  357.     {
  358.         desorden = false;
  359.         nodo = lista->inicio;
  360.         while (nodo != NULL && nodo->SIG != NULL)
  361.         {
  362.             if (1 == comparar_dato(3, &nodo->datos,&nodo->SIG->datos))
  363.             {
  364.                 desorden = true;
  365.                 //intercambio
  366.                 intercambio(lista, nodo->pos, nodo->SIG->pos);
  367.             }
  368.             else nodo = nodo->SIG;
  369.  
  370.         }
  371.     } while (desorden);
  372.     return 0;
  373. }
  374.  
  375. int eliminar_lista(LISTA *lista)
  376. {
  377.     if (lista == NULL)
  378.         return -4;
  379.     while (lista->tam != 0)
  380.         eliminar_nodo(lista, 1);
  381.     return 0;
  382. }
  383.  
  384. /*************************************** PROGRAMA PRINCIPAL MAIN ************************************************************/
  385.  
  386.  
  387. int main()
  388. {
  389.     LISTA lista;
  390.     int error = 0;
  391.  
  392.     inicializar_lista(&lista);
  393.     error = insertar_en_lista_vacia(&lista);
  394.     imprimir_lista(&lista);
  395.     printf("\nLISTA CON INSERCION AL INICIO\n");
  396.     error = insertar_inicio(&lista);
  397.     imprimir_lista(&lista);
  398.     printf("\nLISTA CON INSERCION AL FINAL\n");
  399.     error = insertar_final(&lista);
  400.     imprimir_lista(&lista);
  401.     printf("\nLISTA INSERTANDO EN POSICION 2\n");
  402.     error = insertar_en_posicion(&lista, 2);
  403.     imprimir_lista(&lista);
  404.     printf("\nLISTA INSERTANDO EN POSICION 5\n");
  405.     error = insertar_en_posicion(&lista, 5);
  406.     imprimir_lista(&lista);
  407.     printf("\nINTERCAMBIAR ELEMENTOS 2 Y 3\n");
  408.     error = intercambio(&lista, 2, 3);
  409.     imprimir_lista(&lista);
  410.     printf("\nLISTA ELIMINANDO EN POSICION 3\n");
  411.     error = eliminar_nodo(&lista, 3);
  412.     imprimir_lista(&lista);
  413.     puts("EN ORDEN");
  414.     ordenar_lista_nombre(&lista);
  415.     imprimir_lista(&lista);
  416.     eliminar_lista(&lista);
  417.     return 0;
  418. }
Advertisement
Add Comment
Please, Sign In to add comment