ucx/list.c

Wed, 10 Oct 2012 14:26:53 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 10 Oct 2012 14:26:53 +0200
changeset 65
7b2f2cab6348
parent 37
ec296899d12f
child 67
27e67e725d35
permissions
-rw-r--r--

added _Bool macro for cplusplus

universe@10 1 #include "list.h"
olaf@2 2
universe@18 3 UcxList *ucx_list_clone(UcxList *l, copy_func fnc, void *data) {
universe@18 4 UcxList *ret = NULL;
universe@18 5 while (l != NULL) {
universe@18 6 if (fnc != NULL) {
universe@18 7 ret = ucx_list_append(ret, fnc(l->data, data));
universe@18 8 } else {
universe@18 9 ret = ucx_list_append(ret, l->data);
universe@18 10 }
universe@18 11 l = l->next;
universe@18 12 }
universe@18 13 return ret;
universe@18 14 }
universe@18 15
universe@18 16 int ucx_list_equals(UcxList *l1, UcxList *l2, cmp_func fnc, void* data) {
universe@18 17 if (l1 == l2) return 1;
universe@18 18
universe@18 19 while (l1 != NULL && l2 != NULL) {
universe@18 20 if (fnc == NULL) {
universe@18 21 if (l1->data != l2->data) return 0;
universe@18 22 } else {
universe@18 23 if (fnc(l1->data, l2->data, data) != 0) return 0;
universe@18 24 }
universe@18 25 l1 = l1->next;
universe@18 26 l2 = l2->next;
universe@18 27 }
universe@18 28
universe@18 29 return (l1 == NULL && l2 == NULL);
universe@18 30 }
universe@18 31
universe@10 32 void ucx_list_free(UcxList *l) {
universe@10 33 UcxList *e = l, *f;
universe@10 34 while (e != NULL) {
universe@10 35 f = e;
universe@10 36 e = e->next;
universe@10 37 free(f);
universe@10 38 }
universe@10 39 }
universe@10 40
universe@10 41 UcxList *ucx_list_append(UcxList *l, void *data) {
universe@10 42 UcxList *nl = (UcxList*) malloc(sizeof(UcxList));
universe@10 43 if (nl == NULL) return NULL;
universe@10 44
universe@10 45 nl->data = data;
universe@10 46 nl->next = NULL;
universe@10 47 if (l == NULL) {
universe@10 48 return nl;
universe@10 49 } else {
universe@10 50 UcxList *t = ucx_list_last(l);
universe@10 51 t->next = nl;
universe@10 52 return l;
universe@10 53 }
universe@10 54 }
universe@10 55
universe@10 56 UcxList *ucx_list_prepend(UcxList *l, void *data) {
universe@10 57 UcxList *nl = ucx_list_append(NULL, data);
universe@10 58 if (nl == NULL) return NULL;
universe@10 59
universe@10 60 if (l != NULL) {
universe@10 61 nl->next = l;
universe@10 62 }
universe@10 63 return nl;
universe@10 64 }
universe@10 65
universe@10 66 UcxList *ucx_list_concat(UcxList *l1, UcxList *l2) {
universe@10 67 if (l1 == NULL) {
universe@10 68 return l2;
universe@10 69 } else {
universe@10 70 UcxList *last = ucx_list_last(l1);
universe@10 71 last->next = l2;
universe@10 72 return l1;
universe@10 73 }
universe@10 74 }
universe@10 75
universe@10 76 UcxList *ucx_list_last(UcxList *l) {
universe@10 77 if (l == NULL) return NULL;
universe@10 78
universe@10 79 UcxList *e = l;
universe@10 80 while (e->next != NULL) {
universe@10 81 e = e->next;
universe@10 82 }
universe@10 83 return e;
universe@10 84 }
universe@10 85
universe@10 86 UcxList *ucx_list_get(UcxList *l, int index) {
universe@10 87 if (l == NULL) return NULL;
universe@10 88
universe@10 89 UcxList *e = l;
universe@10 90 while (e->next != NULL && index > 0) {
universe@10 91 e = e->next;
universe@10 92 index--;
universe@10 93 }
universe@10 94
universe@10 95 return index == 0 ? e : NULL;
universe@10 96 }
universe@10 97
universe@10 98 size_t ucx_list_size(UcxList *l) {
universe@10 99 if (l == NULL) return 0;
universe@10 100
universe@10 101 UcxList *e = l;
universe@10 102 size_t s = 1;
universe@10 103 while (e->next != NULL) {
universe@10 104 e = e->next;
universe@10 105 s++;
universe@10 106 }
universe@10 107
universe@10 108 return s;
universe@10 109 }
universe@10 110
universe@37 111 UcxList *ucx_list_sort_merge(int length,
universe@37 112 UcxList* ls, UcxList* rs, UcxList* le, UcxList* re,
universe@37 113 cmp_func fnc, void* data) {
universe@37 114 UcxList *sorted[length];
universe@37 115 UcxList *rc, *lc;
universe@35 116
universe@37 117 lc = ls; rc = rs;
universe@37 118 int n = 0;
universe@37 119 while (lc != le && rc != re) {
universe@37 120 if (fnc(lc->data, rc->data, data) <= 0) {
universe@37 121 sorted[n] = lc;
universe@37 122 lc = lc->next;
universe@37 123 } else {
universe@37 124 sorted[n] = rc;
universe@37 125 rc = rc->next;
universe@35 126 }
universe@37 127 n++;
universe@37 128 }
universe@37 129 while (lc != le) {
universe@37 130 sorted[n] = lc;
universe@37 131 lc = lc->next;
universe@37 132 n++;
universe@37 133 }
universe@37 134 while (rc != re) {
universe@37 135 sorted[n] = rc;
universe@37 136 rc = rc->next;
universe@37 137 n++;
universe@35 138 }
universe@35 139
universe@37 140 // Update pointer
universe@37 141 for (int i = 0 ; i < length-1 ; i++) {
universe@37 142 sorted[i]->next = sorted[i+1];
universe@37 143 }
universe@37 144 sorted[length-1]->next = NULL;
universe@35 145
universe@37 146 return sorted[0];
universe@35 147 }
universe@35 148
universe@36 149 UcxList *ucx_list_sort(UcxList *l, cmp_func fnc, void *data) {
universe@35 150 if (l == NULL) {
universe@35 151 return NULL;
universe@35 152 }
universe@37 153
universe@37 154 UcxList *lc;
universe@37 155 int ln = 1;
universe@37 156
universe@37 157 UcxList *ls = l, *le;
universe@37 158 lc = ls;
universe@37 159 while (lc->next != NULL && fnc(lc->next->data, lc->data, data) > 0) {
universe@37 160 lc = lc->next;
universe@37 161 ln++;
universe@37 162 }
universe@37 163 le = lc->next;
universe@37 164
universe@37 165 UcxList *rs = le, *re;
universe@37 166 if (rs == NULL) {
universe@37 167 return l; // this list is already sorted :)
universe@37 168 } else {
universe@37 169 UcxList *rc;
universe@37 170 int rn = 1;
universe@37 171 rc = rs;
universe@37 172 while (rc->next != NULL && fnc(rc->next->data, rc->data, data) > 0) {
universe@37 173 rc = rc->next;
universe@37 174 rn++;
universe@37 175 }
universe@37 176 re = rc->next;
universe@37 177
universe@37 178 // Something left? Sort it!
universe@37 179 UcxList *remainder = re;
universe@37 180 size_t remainder_length = ucx_list_size(remainder);
universe@37 181 if (remainder != NULL) {
universe@37 182 remainder = ucx_list_sort(remainder, fnc, data);
universe@37 183 }
universe@37 184
universe@37 185 // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them
universe@37 186 UcxList *sorted = ucx_list_sort_merge(ln+rn,
universe@37 187 ls, rs, le, re,
universe@37 188 fnc, data);
universe@37 189
universe@37 190 // merge sorted list with (also sorted) remainder
universe@37 191 l = ucx_list_sort_merge(ln+rn+remainder_length,
universe@37 192 sorted, remainder, NULL, NULL,
universe@37 193 fnc, data);
universe@37 194
universe@35 195 return l;
universe@35 196 }
universe@35 197 }
universe@35 198
universe@23 199 /* list specific functions */
universe@23 200 UcxList *ucx_list_remove(UcxList *l, UcxList *e) {
universe@23 201 if (e == l) {
universe@23 202 l = e->next;
universe@23 203 free(e);
universe@23 204 } else {
universe@23 205 UcxList *f = l;
universe@23 206 while (f->next != NULL && f->next != e) {
universe@23 207 f = f->next;
universe@23 208 }
olaf@31 209 /* perform remove if this element is found in this list */
universe@23 210 if (f->next == e) {
universe@23 211 f->next = e->next;
universe@23 212 free(e);
universe@23 213 }
universe@23 214 }
universe@23 215 return l;
universe@24 216 }

mercurial