Advertisement
Guest User

Untitled

a guest
Mar 26th, 2019
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.08 KB | None | 0 0
  1. #include <dllist.h>
  2.  
  3. #include <assert.h>
  4. #include <stdlib.h>
  5.  
  6. dllist *
  7. dl_new(void (*delfunc)(void *))
  8. {
  9. dllist *list = malloc(sizeof *list);
  10.  
  11. if (list != NULL) {
  12. list->delfunc = delfunc;
  13. list->count = 0;
  14. list->first = NULL;
  15. list->last = NULL;
  16. }
  17.  
  18. return list;
  19. }
  20.  
  21. void
  22. dl_clear(dllist *list)
  23. {
  24. if (list == NULL)
  25. return;
  26. while (dl_count(list))
  27. dl_remove(list, dl_first(list));
  28. }
  29.  
  30. void
  31. dl_delete(dllist *list)
  32. {
  33. dl_clear(list);
  34. free(list);
  35. }
  36.  
  37. static dlnode *
  38. dl_add_between(dllist *list, void *data, dlnode *prev, dlnode *next)
  39. {
  40. dlnode *node;
  41.  
  42. assert((prev == NULL || prev->next == next) &&
  43. (next == NULL || next->prev == prev));
  44. if ((node = malloc(sizeof *node)) == NULL)
  45. return NULL;
  46. node->data = data;
  47.  
  48. node->prev = prev;
  49. node->next = next;
  50. if (prev)
  51. prev->next = node;
  52. else
  53. list->first = node;
  54. if (next)
  55. next->prev = node;
  56. else
  57. list->last = node;
  58. list->count++;
  59.  
  60. return node;
  61. }
  62.  
  63. dlnode *
  64. dl_insert(dllist *list, void *data, dlnode *node)
  65. {
  66. if (node)
  67. return dl_add_between(list, data, node->prev, node);
  68. else
  69. return dl_add_between(list, data, NULL, list->first);
  70. }
  71.  
  72. dlnode *
  73. dl_add(dllist *list, void *data, dlnode *node)
  74. {
  75. if (node)
  76. return dl_add_between(list, data, node, node->next);
  77. else
  78. return dl_add_between(list, data, list->last, NULL);
  79. }
  80.  
  81. dlnode *
  82. dl_add_sorted(dllist *list, void *data, int (*cmpfunc)(void *, void *))
  83. {
  84. dlnode *node;
  85.  
  86. for (node = dl_first(list); node; node = dl_next(node))
  87. if (cmpfunc(dl_data(node), data) > 0)
  88. return dl_insert(list, data, node);
  89.  
  90. return dl_append(list, data);
  91. }
  92.  
  93. static dlnode *
  94. dl_link(dllist *list, dlnode *link, dlnode *node)
  95. {
  96. if (link) {
  97. node->prev = link;
  98. node->next = link->next;
  99.  
  100. if (link->next)
  101. link->next->prev = node;
  102. else
  103. list->last = node;
  104.  
  105. link->next = node;
  106. } else if (list->first) {
  107. node->prev = NULL;
  108. node->next = list->first;
  109. list->first->prev = node;
  110. list->first = node;
  111. } else {
  112. node->prev = NULL;
  113. node->next = NULL;
  114. list->first = node;
  115. list->last = node;
  116. }
  117. list->count++;
  118. }
  119.  
  120. static dlnode *
  121. dl_unlink(dllist *list, dlnode *node)
  122. {
  123. if (node->prev)
  124. node->prev->next = node->next;
  125. else
  126. list->first = node->next;
  127. if (node->next)
  128. node->next->prev = node->prev;
  129. else
  130. list->last = node->prev;
  131. node->prev = NULL;
  132. node->next = NULL;
  133. list->count--;
  134.  
  135. return node;
  136. }
  137.  
  138. void *
  139. dl_remove(dllist *list, dlnode *node)
  140. {
  141. void *data = NULL;
  142.  
  143. if (node == NULL)
  144. return NULL;
  145.  
  146. dl_unlink(list, node);
  147.  
  148. if (list->delfunc)
  149. list->delfunc(node->data);
  150. else
  151. data = node->data;
  152.  
  153. free(node);
  154.  
  155. return data;
  156. }
  157.  
  158. dlnode *
  159. dl_at(dllist *list, int i)
  160. {
  161. dlnode *node;
  162.  
  163. if (i < 0)
  164. i = dl_count(list) + i;
  165.  
  166. if (i < 0 || i >= dl_count(list))
  167. return NULL;
  168.  
  169. if (i < dl_count(list) / 2) {
  170. node = dl_first(list);
  171. while (node && i--)
  172. node = dl_next(node);
  173. } else {
  174. i = dl_count(list) - 1 - i;
  175. node = dl_last(list);
  176. while (node && i--)
  177. node = dl_prev(node);
  178. }
  179.  
  180. return node;
  181. }
  182.  
  183. dlnode *
  184. dl_search(dllist *list, void *data, int (*cmpfunc)(void *, void *))
  185. {
  186. dlnode *node;
  187.  
  188. for (node = dl_first(list); node; node = dl_next(node))
  189. if (cmpfunc(dl_data(node), data) == 0)
  190. break;
  191.  
  192. return node;
  193. }
  194.  
  195. void
  196. dl_sort(dllist *list, int (*cmpfunc)(void *, void *))
  197. {
  198. dlnode *node = dl_first(list);
  199.  
  200. while (node) {
  201. dlnode *next = dl_next(node);
  202.  
  203. if (next && cmpfunc(dl_data(node), dl_data(next)) > 0) {
  204. dlnode *tmp = node;
  205.  
  206. dl_unlink(list, next);
  207.  
  208. do
  209. tmp = dl_prev(tmp);
  210. while (tmp && cmpfunc(dl_data(tmp), dl_data(next)) > 0);
  211.  
  212. dl_link(list, tmp, next);
  213. } else {
  214. node = next;
  215. }
  216. }
  217. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement