Advertisement
andy_shev

dlsort.c (v2)

May 9th, 2017
472
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.42 KB | None | 0 0
  1. #include <err.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5.  
  6. /* Double linked list implementation */
  7.  
  8. struct list_head {
  9.     struct list_head *prev;
  10.     struct list_head *next;
  11. };
  12.  
  13. #define LIST_HEAD(name) \
  14.     struct list_head name = { &(name), &(name) }
  15.  
  16. static void list_del(struct list_head *entry)
  17. {
  18.     struct list_head *prev = entry->prev;
  19.     struct list_head *next = entry->next;
  20.  
  21.     next->prev = prev;
  22.     prev->next = next;
  23. }
  24.  
  25. static void list_add(struct list_head *new, struct list_head *head)
  26. {
  27.     struct list_head *prev = head->prev;
  28.     struct list_head *next = head;
  29.  
  30.         next->prev = new;
  31.         new->next = next;
  32.         new->prev = prev;
  33.         prev->next = new;
  34. }
  35.  
  36. static int list_empty(const struct list_head *head)
  37. {
  38.         return head->next == head;
  39. }
  40.  
  41. static void list_splice(const struct list_head *list, struct list_head *prev, struct list_head *next)
  42. {
  43.     struct list_head *first = list->next;
  44.     struct list_head *last = list->prev;
  45.  
  46.     first->prev = prev;
  47.     prev->next = first;
  48.  
  49.     last->next = next;
  50.     next->prev = last;
  51. }
  52.  
  53. /* The member type of list_head MUST be first in a structure */
  54. #define list_entry(ptr, type, member)       ((type *)(ptr))
  55.  
  56. #define list_first_entry(ptr, type, member) list_entry((ptr)->next, type, member)
  57.  
  58. #define list_next_entry(pos, member)        list_entry((pos)->member.next, typeof(*(pos)), member)
  59.  
  60. #define list_for_each_entry_safe(pos, n, head, member)          \
  61.     for (pos = list_first_entry(head, typeof(*pos), member),    \
  62.            n = list_next_entry(pos, member);            \
  63.          &pos->member != (head);                    \
  64.          pos = n, n = list_next_entry(n, member))
  65.  
  66. /*************************************/
  67.  
  68. struct bus {
  69.     struct list_head node;  /* MUST be first member */
  70.     int route;
  71. };
  72.  
  73. static void dump(struct list_head *bs)
  74. {
  75.     unsigned int i = 0;
  76.     struct bus *b, *_b;
  77.  
  78.     list_for_each_entry_safe(b, _b, bs, node) {
  79.         printf("Bus[%u]: %d\n", i++, b->route);
  80.     }
  81.     printf("\n");
  82. }
  83.  
  84. static void bsfree(struct list_head *bs)
  85. {
  86.     struct bus *b, *_b;
  87.  
  88.     list_for_each_entry_safe(b, _b, bs, node) {
  89.         list_del(&b->node);
  90.         free(b);
  91.     }
  92. }
  93.  
  94. static int prepare(struct list_head *bs)
  95. {
  96.     unsigned int num;
  97.     unsigned int i;
  98.     struct bus *b;
  99.  
  100.     srand(time(NULL));
  101.  
  102.     num = rand() % 16;
  103.  
  104.     for (i = 0; i < num; i++) {
  105.         b = malloc(sizeof(*b));
  106.         if (!b)
  107.             err(1, NULL);
  108.  
  109.         b->route = rand() % 512;
  110.         list_add(&b->node, bs);
  111.     }
  112.  
  113.     return 0;
  114. }
  115.  
  116. /* Quicksort implementation for double-linked list */
  117. static void dlsort(struct list_head *bs)
  118. {
  119.     struct bus *b, *_b, *first;
  120.     LIST_HEAD(less);
  121.     LIST_HEAD(more);
  122.     int pivot;
  123.  
  124.     first = list_first_entry(bs, struct bus, node);
  125.     pivot = first->route;
  126.  
  127.     list_del(&first->node);
  128.     list_for_each_entry_safe(b, _b, bs, node) {
  129.         list_del(&b->node);
  130.         if (b->route >= pivot)
  131.             list_add(&b->node, &more);
  132.         else
  133.             list_add(&b->node, &less);
  134.     }
  135.     list_add(&first->node, &less);
  136.  
  137.     if (!list_empty(&less)) {
  138.         if (less.next != less.prev)
  139.             dlsort(&less);
  140.         list_splice(&less, bs->prev, bs);
  141.     }
  142.  
  143.     if (!list_empty(&more)) {
  144.         if (more.next != more.prev)
  145.             dlsort(&more);
  146.         list_splice(&more, bs->prev, bs);
  147.     }
  148. }
  149.  
  150. static void bssort(struct list_head *bs)
  151. {
  152.     if (list_empty(bs))
  153.         return;
  154.  
  155.     dlsort(bs);
  156. }
  157.  
  158. int main(int argc, char *argv[])
  159. {
  160.     LIST_HEAD(bussit);
  161.     int ret;
  162.  
  163.     ret = prepare(&bussit);
  164.     if (ret)
  165.         return ret;
  166.  
  167.     dump(&bussit);
  168.     bssort(&bussit);
  169.     dump(&bussit);
  170.  
  171.     bsfree(&bussit);
  172.     return 0;
  173. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement