ucx/dlist.c

Wed, 15 Aug 2012 19:32:29 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 15 Aug 2012 19:32:29 +0200
changeset 35
fdabd1240b69
parent 31
91ac86557290
child 36
a9d656e4f7ce
permissions
-rw-r--r--

added mkdir for build directory to makefile + added qsort for list and dlist

     1 #include "dlist.h"
     3 UcxDlist *ucx_dlist_clone(UcxDlist *l, copy_func fnc, void *data) {
     4     UcxDlist *ret = NULL;
     5     while (l != NULL) {
     6         if (fnc != NULL) {
     7             ret = ucx_dlist_append(ret, fnc(l->data, data));
     8         } else {
     9             ret = ucx_dlist_append(ret, l->data);
    10         }
    11         l = l->next;
    12     }
    13     return ret;
    14 }
    16 int ucx_dlist_equals(UcxDlist *l1, UcxDlist *l2, cmp_func fnc, void* data) {
    17     if (l1 == l2) return 1;
    19     while (l1 != NULL && l2 != NULL) {
    20         if (fnc == NULL) {
    21             if (l1->data != l2->data) return 0;
    22         } else {
    23             if (fnc(l1->data, l2->data, data) != 0) return 0;
    24         }
    25         l1 = l1->next;
    26         l2 = l2->next;
    27     }
    29     return (l1 == NULL && l2 == NULL);
    30 }
    32 void ucx_dlist_free(UcxDlist *l) {
    33     UcxDlist *e = l, *f;
    34     while (e != NULL) {
    35         f = e;
    36         e = e->next;
    37         free(f);
    38     }
    39 }
    41 UcxDlist *ucx_dlist_append(UcxDlist *l, void *data)  {
    42     UcxDlist *nl = (UcxDlist*) malloc(sizeof(UcxDlist));
    43     if (nl == NULL) return NULL;
    45     nl->data = data;
    46     nl->next = NULL;
    47     if (l == NULL) {
    48         nl->prev = NULL;
    49         return nl;
    50     } else {
    51         UcxDlist *t = ucx_dlist_last(l);
    52         t->next = nl;
    53         nl->prev = t;
    54         return l;
    55     }
    56 }
    58 UcxDlist *ucx_dlist_prepend(UcxDlist *l, void *data) {
    59     UcxDlist *nl = ucx_dlist_append(NULL, data);
    60     if (nl == NULL) return NULL;
    62     if (l != NULL) {
    63         nl->next = l;
    64         l->prev = nl;
    65     }
    66     return nl;
    67 }
    69 UcxDlist *ucx_dlist_concat(UcxDlist *l1, UcxDlist *l2) {
    70     if (l1 == NULL) {
    71         return l2;
    72     } else {
    73         UcxDlist *last = ucx_dlist_last(l1);
    74         last->next = l2;
    75         l2->prev = last;
    76         return l1;
    77     }
    78 }
    80 UcxDlist *ucx_dlist_last(UcxDlist *l) {
    81     if (l == NULL) return NULL;
    83     UcxDlist *e = l;
    84     while (e->next != NULL) {
    85         e = e->next;
    86     }
    87     return e;
    88 }
    90 UcxDlist *ucx_dlist_get(UcxDlist *l, int index) {
    91     if (l == NULL) return NULL;
    93     UcxDlist *e = l;
    94     while (e->next != NULL && index > 0) {
    95         e = e->next;
    96         index--;
    97     }
    99     return index == 0 ? e : NULL;
   100 }
   102 size_t ucx_dlist_size(UcxDlist *l) {
   103     if (l == NULL) return 0;
   105     UcxDlist *e = l;
   106     size_t s = 1;
   107     while (e->next != NULL) {
   108         e = e->next;
   109         s++;
   110     }
   112     return s;
   113 }
   115 int ucx_dlist_qsort_devide(UcxDlist** list, int l, int r, cmp_func f, void* d) {
   116     int i = l;
   117     int j = r - 1;
   118     void *p = list[r]->data;
   119     UcxDlist *b;
   121     do {
   122         while (i < r && f(list[i]->data, p, d) <= 0) i++;
   123         while (j > l && f(list[j]->data, p, d) >= 0) j--;
   124         if (i < j) {
   125             b = list[i];
   126             list[i] = list[j];
   127             list[j] = b;
   128         }
   129     } while (i < j);
   131     if (f(list[i]->data, p, d) > 0) {
   132         b = list[r];
   133         list[r] = list[i];
   134         list[i] = b;
   135     }
   137     return i;
   138 }
   140 void ucx_dlist_qsort_sort(UcxDlist** list, int l, int r, cmp_func f, void* d) {
   141     if (l < r) {
   142         int m = ucx_dlist_qsort_devide(list, l, r, f, d);
   143         ucx_dlist_qsort_sort(list, l, m-1, f, d);
   144         ucx_dlist_qsort_sort(list, m+1, r, f, d);
   145     }
   146 }
   148 UcxDlist *ucx_dlist_qsort(UcxDlist *l, cmp_func fnc, void *data) {
   149     if (l == NULL) {
   150         return NULL;
   151     }
   152     size_t n = ucx_dlist_size(l);
   153     if (n == 1) {
   154         return l;
   155     }
   157     UcxDlist *entries[n];
   158     entries[0] = l;
   159     for (int i = 1 ; i < n ; i++) {
   160       entries[i] = entries[i-1]->next;
   161     }
   163     ucx_dlist_qsort_sort(entries, 0, n-1, fnc, data);
   165     entries[0]->prev = NULL;
   166     for (int i = 0 ; i < n-1 ; i++) {
   167       entries[i]->next = entries[i+1];
   168       entries[i+1]->prev = entries[i];
   169     }
   170     entries[n-1]->next = NULL;
   172     return entries[0];
   173 }
   175 /* dlist specific functions */
   176 UcxDlist *ucx_dlist_first(UcxDlist *l) {
   177     if (l == NULL) return NULL;
   179     UcxDlist *e = l;
   180     while (e->prev != NULL) {
   181         e = e->prev;
   182     }
   183     return e;
   184 }
   186 UcxDlist *ucx_dlist_remove(UcxDlist *l, UcxDlist *e) {
   187     if (e->prev == NULL) {
   188         if(e->next != NULL) {
   189             e->next->prev = NULL;
   190             l = e->next;
   191         } else {
   192             l = NULL;
   193         }
   195     } else {
   196         e->prev->next = e->next;
   197         e->next->prev = e->prev;
   198     }
   199     free(e);
   200     return l;
   201 }

mercurial