00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <assert.h>
00029 #include <string.h>
00030 #include "list.h"
00031
00032
00053 int list_push(node_l **_x, void *_data)
00054 {
00055 node_l *n = NULL;
00056
00057 assert(_x != NULL);
00058
00059 if((n = (node_l *)malloc(sizeof(node_l))) == NULL) {
00060 return(-1);
00061 } else {
00062 n->data = _data;
00063 n->next = *_x;
00064
00065 *_x = n;
00066 return(0);
00067 }
00068 }
00069
00080 void *list_pop(node_l **_x)
00081 {
00082 node_l *n = NULL;
00083 void *data;
00084
00085 assert(_x != NULL);
00086
00087 if(*_x == NULL)
00088 return(NULL);
00089
00090 n = *_x;
00091 *_x = n->next;
00092 data = n->data;
00093 free(n);
00094
00095 return(data);
00096 }
00097
00109 int list_move(node_l **_dest, node_l **_src)
00110 {
00111 node_l *n = NULL;
00112
00113 assert((_dest != NULL) && (_src != NULL));
00114
00115 if(*_src == NULL)
00116 return(-1);
00117
00118 n = *_src;
00119 *_src = n->next;
00120 n->next = *_dest;
00121 *_dest = n;
00122
00123 return(0);
00124 }
00125
00136 int list_reverse(node_l **_x)
00137 {
00138 node_l *n = NULL;
00139
00140 assert(_x != NULL);
00141
00142 while(list_move(&n, _x) >= 0);
00143 *_x = n;
00144
00145 return(0);
00146 }
00147
00157 node_l *list_sub(const node_l *_x, int _pos)
00158 {
00159 int i = 0;
00160 node_l *n = (node_l *)_x;
00161
00162 assert(_x != NULL);
00163
00164 if(_pos < 0)
00165 return(NULL);
00166
00167 while(i++ < _pos) {
00168 if((n = n->next) == NULL)
00169 return(NULL);
00170 }
00171
00172 return(n);
00173 }
00174
00186 int list_insert(node_l **_x, int _pos, void *_data)
00187 {
00188 node_l *p;
00189
00190 assert(_x != NULL);
00191
00192 if(_pos < 0)
00193 return(-1);
00194
00195 if(_pos == 0)
00196 return(list_push(_x, _data));
00197
00198 if((p = list_sub(*_x, _pos-1)) == NULL)
00199 return(-1);
00200
00201 return(list_push(&(p->next), _data));
00202 }
00203
00214 void *list_remove(node_l **_x, int _pos)
00215 {
00216 node_l *current = *_x;
00217 node_l *next = NULL;
00218 void *data;
00219
00220 assert(_x != NULL);
00221
00222 if(_pos < 0)
00223 return(NULL);
00224
00225 if(*_x == NULL)
00226 return(NULL);
00227
00228 if(_pos == 0)
00229 return(list_pop(_x));
00230
00231 while(--_pos) {
00232 current = current->next;
00233 }
00234
00235 if((next = current->next) == NULL)
00236 return(NULL);
00237
00238 data = next->data;
00239 current->next = next->next;
00240
00241 free(next);
00242 return(data);
00243 }
00244
00255 void *list_get(const node_l *_x, int _pos)
00256 {
00257 int i = 0;
00258
00259 if(_pos < 0)
00260 return(NULL);
00261
00262 while(_x != NULL) {
00263 if(_pos == i++)
00264 return(_x->data);
00265 _x = _x->next;
00266 }
00267
00268 return(NULL);
00269 }
00270
00279 size_t list_size(const node_l *_x)
00280 {
00281 size_t s = 0;
00282
00283 for(; _x != NULL; s++, _x = _x->next);
00284 return(s);
00285 }
00286
00297 node_l *list_join(node_l *_dest, node_l *_src)
00298 {
00299 node_l *n = _dest;
00300
00301 if(_dest == NULL)
00302 return(_src);
00303
00304 if(_src == NULL)
00305 return(_dest);
00306
00307 while(_dest->next != NULL)
00308 _dest = _dest->next;
00309
00310 _dest->next = _src;
00311
00312 return(n);
00313 }
00314
00324 void list_print(const node_l *_a)
00325 {
00326 data *foo;
00327 int i = 0;
00328
00329 while(_a != NULL) {
00330 foo = (data *)_a->data;
00331 printf("%03d: %3d - %s\n", i++, foo->n, foo->str);
00332 _a = _a->next;
00333 }
00334 }
00335
00350
00351 int list_split(node_l **_src, node_l **_front, node_l **_back)
00352 {
00353 node_l *fast, *slow;
00354
00355 assert((_src != NULL) && (_front != NULL) && (_back != NULL));
00356
00357 if((*_src == NULL) || ((*_src)->next == NULL)) {
00358 *_back = NULL;
00359 } else {
00360 slow = *_src;
00361 fast = slow->next;
00362
00363 while(fast != NULL) {
00364 fast = fast->next;
00365 if(fast != NULL) {
00366 slow = slow->next;
00367 fast = fast->next;
00368 }
00369 }
00370 *_back = slow->next;
00371 slow->next = NULL;
00372 }
00373
00374 *_front = *_src;
00375 *_src = NULL;
00376 return(0);
00377 }
00378
00396 int list_merge(node_l **_dest, node_l **_a, node_l **_b, int _cmp(void *, void *))
00397 {
00398 node_l *ret = NULL;
00399 node_l **last = &ret;
00400
00401 assert((_dest != NULL) && (_a != NULL) && (_b != NULL));
00402
00403 for(;;) {
00404 if(*_a == NULL) {
00405 *last = *_b;
00406 break;
00407 }
00408
00409 if(*_b == NULL) {
00410 *last = *_a;
00411 break;
00412 }
00413
00414 if(_cmp((*_a)->data, (*_b)->data) <= 0) {
00415 list_move(last, _a);
00416 } else {
00417 list_move(last, _b);
00418 }
00419
00420 last = &((*last)->next);
00421 }
00422
00423 *_dest = ret;
00424 return(0);
00425 }
00426
00438 int list_sort(node_l **_x, int _cmp(void *, void *))
00439 {
00440 node_l *l, *r;
00441
00442 assert(_x != NULL);
00443
00444 if(*_x == NULL || (*_x)->next == NULL)
00445 return(0);
00446
00447 list_split(_x, &l, &r);
00448
00449 list_sort(&l, _cmp);
00450 list_sort(&r, _cmp);
00451
00452 list_merge(_x, &l, &r, _cmp);
00453
00454 return(0);
00455 }
00456
00473 int list_copy(const node_l *_src, node_l **_dest)
00474 {
00475 assert(_src != NULL);
00476
00477 *_dest = NULL;
00478
00479 while(_src) {
00480 if(list_push(_dest, _src->data)) {
00481 return(-1);
00482 } else {
00483 _src = _src->next;
00484 }
00485 }
00486 return(list_reverse(_dest));
00487 }
00488
00500 int list_realloc(node_l *_x, size_t _sz)
00501 {
00502 void *data;
00503
00504 assert(_x != NULL);
00505
00506 while(_x) {
00507 if((data = malloc(_sz)) == NULL) {
00508 return(-1);
00509 } else {
00510 _x->data = memcpy(data, _x->data, _sz);
00511 _x = _x->next;
00512 }
00513 }
00514 return(0);
00515 }
00516
00529 int list_dup(node_l *_src, node_l **_dest, size_t _sz)
00530 {
00531 assert(_src != NULL);
00532
00533 if(list_copy(_src, _dest) < 0)
00534 return(-1);
00535
00536 if(list_realloc(*_dest, _sz) < 0)
00537 return(-1);
00538
00539 return(0);
00540 }
00541
00552 void list_delete(node_l **_x)
00553 {
00554 assert(_x != NULL);
00555
00556 while(*_x) {
00557 list_pop(_x);
00558 }
00559 }
00560
00571 void list_destroy(node_l **_x)
00572 {
00573 assert(_x != NULL);
00574
00575 while(*_x) {
00576 free(list_pop(_x));
00577 }
00578 }
00579
00588
00589 node_l *list_create123()
00590 {
00591 node_l *n = NULL;
00592 data *a=malloc(sizeof(data)),
00593 *b=malloc(sizeof(data)),
00594 *c=malloc(sizeof(data));
00595
00596 a->n = 1;
00597 strcpy(a->str, "foo");
00598 b->n = 2;
00599 strcpy(b->str, "bar");
00600 c->n = 3;
00601 strcpy(c->str, "snafu");
00602
00603 list_push(&n, a);
00604 list_push(&n, b);
00605 list_push(&n, c);
00606 return(n);
00607 }
00608
00619
00620 int cmp(void *_a, void *_b)
00621 {
00622 data *a = (data *)_a, *b = (data *)_b;
00623
00624 if(a->n < b->n) return(-1);
00625 if(a->n > b->n) return(1);
00626 return(0);
00627 }
00628
00643 int list_foreach(node_l *_x, int _func(void *))
00644 {
00645 int ret = 0;
00646
00647 while(_x) {
00648 ret *= _func(_x->data);
00649 _x = _x->next;
00650 }
00651
00652 return(ret);
00653 }
00654