00001
00002
00003
00004
00005
00006
00007
00014 #include "common.h"
00015 #include "dlist.h"
00016
00017
00021 void dlListInit(dlList *dl)
00022 {
00023 dl->head = (dlNode *)(&dl->nullMiddle);
00024 dl->nullMiddle = NULL;
00025 dl->tail = (dlNode *)(&dl->head);
00026 }
00027
00028
00029
00033 dlList *dlListNew(void)
00034 {
00035 dlList *dl;
00036 AllocVar(dl);
00037 dl->head = (dlNode *)(&dl->nullMiddle);
00038 dl->tail = (dlNode *)(&dl->head);
00039 return dl;
00040 }
00041
00042
00043
00047 void dlListReset(dlList *dl)
00048 {
00049 dlNode *node, *next;
00050 for (node = dl->head; node->next != NULL; node = next)
00051 {
00052 next = node->next;
00053 freeMem(node);
00054 }
00055 dl->head = (dlNode *)(&dl->nullMiddle);
00056 dl->nullMiddle = NULL;
00057 dl->tail = (dlNode *)(&dl->head);
00058 }
00059
00060
00061
00065 void dlListFree(dlList **pList)
00066 {
00067 dlList *list = *pList;
00068 if (list != NULL)
00069 {
00070 dlListReset(list);
00071 freez(pList);
00072 }
00073 }
00074
00075
00076
00081 void dlListFreeAndVals(dlList **pList)
00082 {
00083 dlList *list = *pList;
00084 if (list != NULL)
00085 {
00086 dlNode *node;
00087 for (node = list->head; node->next != NULL; node = node->next)
00088 freeMem(node->val);
00089 dlListFree(pList);
00090 }
00091 }
00092
00093
00094
00095 void dlInsertBetween(dlNode *before, dlNode *after, dlNode *newNode)
00096 {
00097 before->next = newNode;
00098 newNode->prev = before;
00099 newNode->next = after;
00100 after->prev = newNode;
00101 }
00102
00103
00104
00108 void dlAddBefore(dlNode *anchor, dlNode *newNode)
00109 {
00110 dlInsertBetween(anchor->prev, anchor, newNode);
00111 }
00112
00113
00114
00118 void dlAddAfter(dlNode *anchor, dlNode *newNode)
00119 {
00120 dlInsertBetween(anchor, anchor->next, newNode);
00121 }
00122
00123
00124
00128 void dlAddHead(dlList *list, dlNode *newNode)
00129 {
00130 dlNode *head = list->head;
00131 dlInsertBetween(head->prev, head, newNode);
00132 }
00133
00134
00135
00139 void dlAddTail(dlList *list, dlNode *newNode)
00140 {
00141 dlNode *tail = list->tail;
00142 dlInsertBetween(tail, tail->next, newNode);
00143 }
00144
00145
00146
00150 dlNode *dlAddValBefore(dlNode *anchor, void *val)
00151 {
00152 dlNode *node = AllocA(dlNode);
00153 node->val = val;
00154 dlAddBefore(anchor, node);
00155 return node;
00156 }
00157
00158
00159
00163 dlNode *dlAddValAfter(dlNode *anchor, void *val)
00164 {
00165 dlNode *node = AllocA(dlNode);
00166 node->val = val;
00167 dlAddAfter(anchor, node);
00168 return node;
00169 }
00170
00171
00172
00176 dlNode *dlAddValHead(dlList *list, void *val)
00177 {
00178 dlNode *node = AllocA(dlNode);
00179 node->val = val;
00180 dlAddHead(list, node);
00181 return node;
00182 }
00183
00184
00185
00189 dlNode *dlAddValTail(dlList *list, void *val)
00190 {
00191 dlNode *node = AllocA(dlNode);
00192 node->val = val;
00193 dlAddTail(list, node);
00194 return node;
00195 }
00196
00197
00198
00202 void dlRemove(dlNode *node)
00203 {
00204 dlNode *before = node->prev;
00205 dlNode *after = node->next;
00206 before->next = after;
00207 after->prev = before;
00208 node->prev = NULL;
00209 node->next = NULL;
00210 }
00211
00212
00213
00217 void dlRemoveHead(dlList *list)
00218 {
00219 dlRemove(list->head);
00220 }
00221
00222
00223
00227 void dlRemoveTail(dlList *list)
00228 {
00229 dlRemove(list->tail);
00230 }
00231
00232
00233
00237 dlNode *dlPopHead(dlList *list)
00238 {
00239 dlNode *node = list->head;
00240 if (node->next == NULL)
00241 return NULL;
00242 dlRemove(node);
00243 return node;
00244 }
00245
00246
00247
00251 dlNode *dlPopTail(dlList *list)
00252 {
00253 dlNode *node = list->tail;
00254 if (node->prev == NULL)
00255 return NULL;
00256 dlRemove(node);
00257 return node;
00258 }
00259
00260
00261
00265 void dlDelete(dlNode **nodePtr)
00266 {
00267 dlNode *node = *nodePtr;
00268 if (node != NULL)
00269 {
00270 dlRemove(node);
00271 freeMem(node);
00272 }
00273 }
00274
00275
00276
00280 int dlCount(dlList *list)
00281 {
00282 dlNode *node;
00283 int count = 0;
00284
00285 for (node = list->head; !dlEnd(node); node = node->next) {
00286 count++;
00287 }
00288 return count;
00289 }
00290
00291
00292
00293 struct dlSorter
00294
00295 {
00296 dlNode *node;
00297 };
00298
00299
00300
00301 static int (*compareFunc)(const void *elem1, const void *elem2);
00302
00303
00304
00305
00306 static int dlNodeCmp(const void *elem1, const void *elem2)
00307
00308 {
00309 struct dlSorter *a = (struct dlSorter *)elem1;
00310 struct dlSorter *b = (struct dlSorter *)elem2;
00311 return compareFunc(&a->node->val, &b->node->val);
00312 }
00313
00314
00315
00321 void dlSort(dlList *list, int (*compare )(const void *elem1, const void *elem2))
00322 {
00323 int len = dlCount(list);
00324
00325 if (len > 1)
00326 {
00327
00328 struct dlSorter *sorter = needLargeMem(len * sizeof(sorter[0])), *s;
00329 dlNode *node;
00330 int i;
00331
00332 for (i=0, node = list->head; i<len; ++i, node = node->next)
00333 {
00334 s = &sorter[i];
00335 s->node = node;
00336 }
00337 compareFunc = compare;
00338 qsort(sorter, len, sizeof(sorter[0]), dlNodeCmp);
00339 dlListInit(list);
00340 for (i=0; i<len; ++i)
00341 dlAddTail(list, sorter[i].node);
00342 freeMem(sorter);
00343 }
00344 }
00345
00346
00347
00351 int dlEmpty(dlList *list)
00352 {
00353 return dlIsEmpty(list);
00354 }
00355
00356
00357
00361 dlNode *dlGetBeforeHead(dlList *list)
00362 {
00363 if (dlEmpty(list))
00364 return list->head;
00365 else
00366 return list->head->prev;
00367 }
00368
00369
00370
00374 dlNode *dlGetAfterTail(dlList *list)
00375 {
00376 if (dlEmpty(list))
00377 return list->tail;
00378 else
00379 return list->tail->next;
00380 }
00381
00382
00383
00387 void dlCat(dlList *a, dlList *b)
00388 {
00389 dlNode *node;
00390 while ((node = dlPopHead(b)) != NULL)
00391 dlAddTail(a, node);
00392 }
00393
00394
00395
00399 dlNode *dlValInList(dlList *list, void *val)
00400 {
00401 dlNode *node;
00402 for (node = list->head; !dlEnd(node); node = node->next)
00403 if (node->val == val)
00404 return node;
00405 return NULL;
00406 }