list.c (3930B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #include "list.h" 5 6 7 static int __lqsort(List *p, List *tail, 8 int (* cmp)(void *, void *)); 9 static void __lprint(List *p, List *tail, void (* pfnc)(void *)); 10 11 static int list_count = 0; 12 13 /* 14 * Laddfront() adds item in front of List p. 15 * Returns NULL if error occured. 16 */ 17 List * 18 laddfront(List *p, void *item) 19 { 20 if (item == NULL) { 21 // TODO: should print some message ?? 22 //fprintf(stderr, "laddfront: Error. Item is NULL\n"); 23 return NULL; 24 } 25 26 List *newlp; 27 if((newlp = (List *)malloc(sizeof(List))) == NULL) { 28 fprintf(stderr, "laddfront: Error. Could not allocate memory.\n"); 29 return NULL; 30 } 31 list_count++; 32 newlp->item = item; 33 newlp->next = p; 34 return newlp; 35 } 36 37 /* 38 * Lfree() frees List *p. Its items should be freed elsewhere. 39 */ 40 void 41 lfree(List *p) 42 { 43 List *q; 44 for (q = p; q != NULL; q = p) { 45 p = q->next; 46 free(q); 47 list_count--; 48 } 49 } 50 51 /* 52 * Lfreei() frees List *p. Its items are freed using ifree(). 53 */ 54 void 55 lfreei(List *p, void (* ifree)(void *)) 56 { 57 List *q; 58 for (q = p; q != NULL; q = p) { 59 p = q->next; 60 ifree(q->item); 61 free(q); 62 list_count--; 63 } 64 } 65 66 int 67 get_list_count(void) 68 { 69 return list_count; 70 } 71 72 void 73 lprint(List *p, void (* pfnc)(void *)) 74 { 75 __lprint(p, NULL, pfnc); 76 } 77 78 void 79 __lprint(List *p, List *tail, void (* pfnc)(void *)) 80 { 81 if (p == NULL) { 82 printf("\n"); 83 } 84 for (;p != tail && p != NULL; p = p->next) { 85 if (p->item == NULL) { 86 fprintf(stderr, "__lprint: Error. Item is NULL\n"); 87 return; 88 } 89 (*pfnc)(p->item); 90 printf("%s", p->next == tail ? "\n" : "->"); 91 } 92 if (p != tail) { 93 fprintf(stderr, "__lprint: Warning. Tail not found in the list.\n"); 94 } 95 } 96 97 /* 98 * Bubble sort. returns -1 if error occured, 0 if succeed. 99 */ 100 int 101 lbsort(List *p, int (* cmp)(void *, void *)) 102 { 103 List *q; 104 105 for (;p != NULL && p->next != NULL; p = p->next) { 106 for (q = p->next; q != NULL; q = q->next) { 107 if (p->item == NULL || q->item == NULL) { 108 fprintf(stderr, "lbsort: Error. List without item.\n"); 109 return -1; 110 } 111 if (cmp(p->item, q->item) > 0) { 112 lswap(p, q); 113 } 114 } 115 } 116 return 0; 117 } 118 119 /* 120 * Quick sort 121 * Lqsort() sorts entire List p, according to the results of cmp(). 122 * __lqsort() sorts the List from p to the item before tail. 123 * Tail can be NULL. This case __lqsort() sorts entire List. 124 * Returns 0 if succeed, -1 if error occured. 125 */ 126 int 127 lqsort(List *p, int (* cmp)(void *, void *)) 128 { 129 return __lqsort(p, NULL, cmp); 130 } 131 132 static int 133 __lqsort(List *p, List *tail, int (* cmp)(void *, void *)) 134 { 135 if (p == tail || p->next == tail) 136 return 0; 137 138 List *pivot, *q, *last; 139 int i; 140 141 /* select the pivot randomly */ 142 for (i = 0, q = p; q != tail; q = q->next) { 143 if (rand() % ++i == 0) 144 pivot = q; 145 } 146 147 lswap(p, pivot); 148 last = p; 149 for (q = p->next; q != tail; q = q->next) { 150 if (p->item == NULL || q->item == NULL) { 151 fprintf(stderr, "lbsort: Error. List without item.\n"); 152 return -1; 153 } 154 if (cmp(p->item, q->item) > 0) { 155 last = last->next; 156 lswap(last, q); 157 } 158 } 159 lswap(p, last); 160 161 __lqsort(last->next, tail, cmp); 162 __lqsort(p, last, cmp); 163 164 return 0; 165 } 166 167 void 168 lswap(List *p, List *q) 169 { 170 if (p == NULL || q == NULL) 171 return; 172 void *tmp; 173 tmp = p->item; 174 p->item = q->item; 175 q->item = tmp; 176 } 177 178 /* 179 * Leqa() returns 1 if two Lists are identicall, 0 if not. 180 * Only checks the address of each items. 181 */ 182 int 183 leqa(List *p, List *q) 184 { 185 for (;p != NULL && q != NULL; p = p->next, q = q->next) { 186 if (p->item != q->item) 187 return 0; 188 } 189 if (p == NULL && q == NULL) 190 return 1; 191 return 0; 192 } 193 194 /* 195 * Leqi() returns 1 if two Lists are identicall, 0 if not. 196 * Compares each items with eq(). 197 */ 198 int 199 leqi(List *p, List *q, int (*eq)(void *, void*)) 200 { 201 for (;p != NULL && q != NULL; p = p->next, q = q->next) { 202 if (!eq(p->item, q->item)) 203 return 0; 204 } 205 if (p == NULL && q == NULL) 206 return 1; 207 return 0; 208 } 209 210 unsigned long int 211 llen(List *p) 212 { 213 unsigned long len = 0; 214 for (; p != NULL; p = p->next) 215 len++; 216 return len; 217 }