Advertisement
Miquel_Fuster

Insertion Sort in a doubly linked list

Mar 27th, 2022 (edited)
1,409
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.87 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4.  
  5. typedef struct node {
  6.     int data;
  7.     struct node* prev;
  8.     struct node* next;
  9. } node;
  10.  
  11. void print(node *list) {
  12.     node *pointer = list;
  13.     while(pointer) {
  14.         printf("%d ", pointer->data);
  15.         pointer = pointer->next;
  16.     }
  17.     putchar('\n');
  18. }
  19.  
  20. void insertion_sort(node **head) {
  21.     // evito una lista vacía
  22.     if(!*head) {
  23.         return;
  24.     }
  25.  
  26.     // se recorre la lista de izquierda a derecha
  27.     for(node *pointer=(*head)->next; pointer; pointer=pointer->next) {
  28.         // nodo auxiliar para recorrer la lista al revés en busca de datos menores
  29.         node *aux = pointer;
  30.         // flag para mantener pointer en su sitio
  31.         bool flag = true;
  32.         // ordenando de forma ascendente
  33.         while(aux->prev && aux->data < aux->prev->data) {
  34.             // se inicia el intercambio de nodos, el actual por el anterior a este --------
  35.             // se empieza por hacer que los nodos en los extremos de la pareja actual apunten
  36.             // a la pareja actual de forma intercambiada. Por ejemplo: sean los cuatro nodos
  37.             // A B [C] D
  38.             // C es el nodo actual a comparar
  39.             // A->next apunta a B
  40.             // D->prev apunta a C
  41.             // en el intercambio
  42.             // A->next debe apuntar a C
  43.             // D->prev debe apuntar a B
  44.             // para que esto sea así se debe comprobar que A y D existan para poder operar
  45.  
  46.             // contiene la dirección del nodo previo al previo del actual. Siendo el actual C, A.
  47.             node *app = aux->prev->prev;
  48.             // si dicho nodo existe, el siguiente a este deberá ser el actual. A->next apunta a C.
  49.             if(app) {
  50.                 aux->prev->prev->next = aux;
  51.             }
  52.             // si existe un nodo que sea siguiente al actual, su previo debe apuntar al nodo anterior al actual. D->prev apunta a B.
  53.             if(aux->next) {
  54.                 aux->next->prev = aux->prev;
  55.             }
  56.  
  57.             // intercambio entre la pareja de nodos.
  58.             // B->prev apunta a C
  59.             aux->prev->prev = aux;
  60.             // B->next apunta a D
  61.             aux->prev->next = aux->next;
  62.             // C->next apunta a B
  63.             aux->next = aux->prev;
  64.             // C->prev apunta a A
  65.             aux->prev = app;
  66.  
  67.             // el primer intercambio se hará lo más a la derecha de la sublista
  68.             // por lo tanto cuándo se efectua el primer intercambio se debe actualizar
  69.             // pointer para que apunte al nodo intercambiado. El flag va a evitar que
  70.             // si se va hacia la izquierda pointer también vaya a la izquierda.
  71.             if(flag) {
  72.                 pointer = aux->next;
  73.                 flag = false;
  74.             }
  75.  
  76.             // la cabeza de la lista se debe actualizar si hay algún nodo que ha caído en
  77.             // esa posición
  78.             if(!aux->prev)
  79.                 *head = aux;          
  80.         }
  81.     }
  82. }
  83.  
  84. bool add(node **head, int data) {
  85.     node *new = malloc(sizeof(node));
  86.     if(!new) {
  87.         return false;
  88.     }
  89.  
  90.     new->data = data;
  91.     new->next = NULL;
  92.  
  93.     if(*head) {
  94.         node *pointer = *head;
  95.         while(pointer->next) {
  96.             pointer = pointer->next;
  97.         }
  98.         pointer->next = new;
  99.         new->prev = pointer;
  100.     } else {
  101.         new->prev = NULL;
  102.         *head = new;
  103.     }
  104.  
  105.     return true;
  106. }
  107.  
  108. void drop(node **head) {
  109.     node *aux;
  110.     if(!*head) {
  111.         return;
  112.     }
  113.  
  114.     while(*head) {
  115.         aux = *head;
  116.         *head = (*head)->next;
  117.         free(aux);
  118.     }
  119. }
  120.  
  121. int main() {
  122.     node *list = NULL;
  123.     add(&list, 5);
  124.     add(&list, 2);
  125.     add(&list, 4);
  126.     add(&list, 1);
  127.     add(&list, 3);
  128.     add(&list, 0);
  129.  
  130.     print(list);
  131.    
  132.     insertion_sort(&list);
  133.     print(list);
  134.  
  135.     drop(&list);
  136. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement