Advertisement
drankinatty

Singly Linked List of Integers (mergesort)

Feb 5th, 2020
360
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.33 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. #ifndef NNODES
  6. #define NNODES 10
  7. #endif
  8.  
  9. typedef struct node_t {     /* list node */
  10.     int data;
  11.     struct node_t *next;
  12. } node_t;
  13.  
  14. typedef struct {            /* list wrapper with head & tail pointers */
  15.     node_t *head, *tail;
  16. } list_t;
  17.  
  18. /** add node at end of list, update tail to end */
  19. node_t *add (list_t *l, int v)
  20. {
  21.     node_t *node = malloc (sizeof *node);   /* allocate node */
  22.     if (!node) {                            /* validate allocation */
  23.         perror ("malloc-node");
  24.         return NULL;
  25.     }
  26.     node->data = v;                         /* initialize members values */
  27.     node->next = NULL;
  28.  
  29.     if (!l->head)                   /* if 1st node, node is head/tail */
  30.         l->head = l->tail = node;
  31.     else {                          /* otherwise */
  32.         l->tail->next = node;       /* add at end, update tail pointer */
  33.         l->tail = node;
  34.     }
  35.  
  36.     return node;    /* return new node */
  37. }
  38.  
  39. /* split list l into lists a & b */
  40. void split (list_t *l, list_t *a)
  41. {
  42.     node_t  *pa = l->head,
  43.             *pb = pa->next;
  44.  
  45.     while (pb) {
  46.         pb = pb->next;
  47.         if (pb) {
  48.             pa = pa->next;
  49.             pb = pb->next;
  50.         }
  51.     }
  52.  
  53.     a->tail = l->tail;
  54.     l->tail = pa;
  55.  
  56.     a->head = pa->next;
  57.     pa->next = NULL;
  58. }
  59.  
  60. node_t *mergesorted (node_t *a, node_t *b)
  61. {
  62.     node_t  *res = NULL;
  63.  
  64.     /* Base cases */
  65.     if (!a)
  66.         return (b);
  67.     else if (!b)
  68.         return (a);
  69.  
  70.     /* Pick either a or b, and recur */
  71.     // if (a->data <= b->data) {       /* ascending */
  72.     if (a->data > b->data) {        /* descending */
  73.         res = a;
  74.         res->next = mergesorted (a->next, b);
  75.     }
  76.     else {
  77.         res = b;
  78.         res->next = mergesorted (a, b->next);
  79.     }
  80.     return (res);
  81. }
  82.  
  83. /* sorts the linked list by changing next pointers (not data) */
  84. void mergesort (list_t *l)
  85. {
  86.     list_t la;
  87.     node_t *head = l->head;
  88.  
  89.     /* Base case -- length 0 or 1 */
  90.     if (!head || !head->next) {
  91.         return;
  92.     }
  93.  
  94.     /* Split head into 'a' and 'b' sublists */
  95.     split (l, &la);
  96.  
  97.     /* Recursively sort the sublists */
  98.     mergesort(l);
  99.     mergesort(&la);
  100.  
  101.     /* answer = merge the two sorted lists together */
  102.     l->head = mergesorted (l->head, la.head);
  103.  
  104.     /* set tail pointer to last node after sort */
  105.     for (head = l->head; head; head = head->next)
  106.         l->tail = head;
  107. }
  108.  
  109. /** print all nodes in list */
  110. void prn (list_t *l)
  111. {
  112.     if (!l->head) {
  113.         puts ("list-empty");
  114.         return;
  115.     }
  116.     for (node_t *n = l->head; n; n = n->next)
  117.         printf (" %d", n->data);
  118.     putchar ('\n');
  119. }
  120.  
  121. /** delete all nodes in list */
  122. void del_list (list_t *l)
  123. {
  124.     node_t *n = l->head;
  125.     while (n) {
  126.         node_t *victim = n;
  127.         n = n->next;
  128.         free (victim);
  129.     }
  130. }
  131.  
  132. int main (void) {
  133.  
  134.     int arr[] = {12, 11, 10, 7, 4, 14, 8, 16, 20, 19,
  135.                   2, 9, 1, 13, 17, 6, 15, 5, 3, 18};
  136.     unsigned asz = sizeof arr / sizeof *arr;
  137.     list_t l = { NULL, NULL };      /* initialize list pointers NULL */
  138.  
  139.     for (unsigned i = 0; i < asz; i++)
  140.         add (&l, arr[i]);
  141.  
  142.     prn (&l);
  143.     mergesort(&l);
  144.     prn (&l);
  145.  
  146.     del_list (&l);      /* delete list (does nothing list-empty) */
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement