aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2020-08-02 10:55:59 +0200
committerThomas Schmucker <ts@its1.de>2020-08-02 10:55:59 +0200
commit09a96907962ac2d1115f545e194f06ea4fd3db19 (patch)
tree5df107d0f820b024795ebe3283fa48298c67d2f0
parente7986e3e11b9ca91079bacae7fc2f79dce515f5d (diff)
downloaddata-structures-09a96907962ac2d1115f545e194f06ea4fd3db19.tar.gz
data-structures-09a96907962ac2d1115f545e194f06ea4fd3db19.tar.bz2
data-structures-09a96907962ac2d1115f545e194f06ea4fd3db19.zip
reformat codedlist_sort_xxx
-rw-r--r--dlist.c151
1 files changed, 83 insertions, 68 deletions
diff --git a/dlist.c b/dlist.c
index 140d3a3..c006f20 100644
--- a/dlist.c
+++ b/dlist.c
@@ -1,10 +1,10 @@
1/* dlist -- double linked list */ 1/* dlist -- double linked list */
2 2
3/* Standard C */ 3/* Standard C */
4#include <assert.h>
5#include <stdbool.h>
4#include <stdio.h> 6#include <stdio.h>
5#include <stdlib.h> 7#include <stdlib.h>
6#include <stdbool.h>
7#include <assert.h>
8#include <time.h> 8#include <time.h>
9 9
10/* Project */ 10/* Project */
@@ -18,7 +18,7 @@ struct dlist {
18 18
19struct dlist_element { 19struct dlist_element {
20 struct dlist_element *prev, *next; 20 struct dlist_element *prev, *next;
21 T data; 21 T data;
22}; 22};
23 23
24void 24void
@@ -32,7 +32,7 @@ static struct dlist_element *
32create_element(T data) 32create_element(T data)
33{ 33{
34 struct dlist_element *element; 34 struct dlist_element *element;
35 35
36 element = malloc(sizeof *element); 36 element = malloc(sizeof *element);
37 if ( element != NULL ) { 37 if ( element != NULL ) {
38 element->data = data; 38 element->data = data;
@@ -45,21 +45,21 @@ struct dlist_element *
45dlist_push_front(struct dlist *dlist, T data) 45dlist_push_front(struct dlist *dlist, T data)
46{ 46{
47 struct dlist_element *element; 47 struct dlist_element *element;
48 48
49 element = create_element(data); 49 element = create_element(data);
50 if ( element != NULL ) { 50 if ( element != NULL ) {
51 element->prev = NULL; /* Vorgänger ist in jedem Fall NULL */ 51 element->prev = NULL; /* Vorgänger ist in jedem Fall NULL */
52 52
53 if ( dlist->head == NULL ) { /* empty list */ 53 if ( dlist->head == NULL ) { /* empty list */
54 element->next = NULL; 54 element->next = NULL;
55 dlist->tail = element; 55 dlist->tail = element;
56 } 56 }
57 else { /* non empty list */ 57 else { /* non empty list */
58 element->next = dlist->head; 58 element->next = dlist->head;
59 element->next->prev = element; 59 element->next->prev = element;
60 } 60 }
61 61
62 dlist->head = element; /* Neues Element ist in jedem Fall der neue Anfang! */ 62 dlist->head = element; /* Neues Element ist in jedem Fall der neue Anfang! */
63 } 63 }
64 else 64 else
65 ERROR("out of memory"); 65 ERROR("out of memory");
@@ -71,21 +71,21 @@ struct dlist_element *
71dlist_push_back(struct dlist *dlist, T data) 71dlist_push_back(struct dlist *dlist, T data)
72{ 72{
73 struct dlist_element *element; 73 struct dlist_element *element;
74 74
75 element = create_element(data); 75 element = create_element(data);
76 if ( element != NULL ) { 76 if ( element != NULL ) {
77 element->next = NULL; /* Nachfolger ist in jedem Fall NULL */ 77 element->next = NULL; /* Nachfolger ist in jedem Fall NULL */
78 78
79 if ( dlist->head == NULL ) { /* empty list */ 79 if ( dlist->head == NULL ) { /* empty list */
80 element->prev = NULL; 80 element->prev = NULL;
81 dlist->head = element; 81 dlist->head = element;
82 } 82 }
83 else { /* non empty list */ 83 else { /* non empty list */
84 element->prev = dlist->tail; 84 element->prev = dlist->tail;
85 element->prev->next = element; 85 element->prev->next = element;
86 } 86 }
87 87
88 dlist->tail = element; /* Neues Element ist in jedem Fall das neue Ende! */ 88 dlist->tail = element; /* Neues Element ist in jedem Fall das neue Ende! */
89 } 89 }
90 else 90 else
91 ERROR("out of memory"); 91 ERROR("out of memory");
@@ -141,14 +141,14 @@ struct dlist_element *
141dlist_insert_next(struct dlist *dlist, struct dlist_element *element, T data) 141dlist_insert_next(struct dlist *dlist, struct dlist_element *element, T data)
142{ 142{
143 struct dlist_element *new_element; 143 struct dlist_element *new_element;
144 144
145 new_element = create_element(data); 145 new_element = create_element(data);
146 if ( new_element != NULL ) { 146 if ( new_element != NULL ) {
147 if ( dlist->head == NULL ) { 147 if ( dlist->head == NULL ) {
148 dlist->head = new_element; 148 dlist->head = new_element;
149 dlist->head->prev = NULL; 149 dlist->head->prev = NULL;
150 dlist->head->next = NULL; 150 dlist->head->next = NULL;
151 dlist->tail = new_element; 151 dlist->tail = new_element;
152 } 152 }
153 else { 153 else {
154 new_element->next = element->next; 154 new_element->next = element->next;
@@ -172,14 +172,14 @@ struct dlist_element *
172dlist_insert_prev(struct dlist *dlist, struct dlist_element *element, T data) 172dlist_insert_prev(struct dlist *dlist, struct dlist_element *element, T data)
173{ 173{
174 struct dlist_element *new_element; 174 struct dlist_element *new_element;
175 175
176 new_element = create_element(data); 176 new_element = create_element(data);
177 if ( new_element != NULL ) { 177 if ( new_element != NULL ) {
178 if ( dlist->head == NULL ) { 178 if ( dlist->head == NULL ) {
179 dlist->head = new_element; 179 dlist->head = new_element;
180 dlist->head->prev = NULL; 180 dlist->head->prev = NULL;
181 dlist->head->next = NULL; 181 dlist->head->next = NULL;
182 dlist->tail = new_element; 182 dlist->tail = new_element;
183 } 183 }
184 else { 184 else {
185 new_element->next = element; 185 new_element->next = element;
@@ -226,7 +226,7 @@ void
226dlist_free(struct dlist *dlist) 226dlist_free(struct dlist *dlist)
227{ 227{
228 struct dlist_element *elem, *next; 228 struct dlist_element *elem, *next;
229 229
230 for ( elem = dlist->head; elem; elem = next ) { 230 for ( elem = dlist->head; elem; elem = next ) {
231 next = elem->next; 231 next = elem->next;
232 free(elem); 232 free(elem);
@@ -285,60 +285,71 @@ dlist_sort_xxx(struct dlist *list)
285 285
286 int insize = 1; 286 int insize = 1;
287 287
288 while (1) { 288 while ( 1 ) {
289 struct dlist_element *p; 289 struct dlist_element *p;
290 290
291 p = list->head; 291 p = list->head;
292 list->head = NULL; 292 list->head = NULL;
293 list->tail = NULL; 293 list->tail = NULL;
294 294
295 int nmerges = 0; /* count number of merges we do in this pass */ 295 int nmerges = 0; /* count number of merges we do in this pass */
296
297 while (p) {
298 296
297 while ( p ) {
299 struct dlist_element *q; 298 struct dlist_element *q;
300 299
301 nmerges++; /* there exists a merge to be done */ 300 nmerges++; /* there exists a merge to be done */
302 /* step `insize' places along from p */ 301 /* step `insize' places along from p */
303 q = p; 302 q = p;
304 int psize = 0; 303 int psize = 0;
305 for (int i = 0; i < insize; i++) { 304 for ( int i = 0; i < insize; i++ ) {
306 psize++; 305 psize++;
307 q = q->next; 306 q = q->next;
308 if (!q) break; 307 if ( !q )
308 break;
309 } 309 }
310 310
311 /* if q hasn't fallen off end, we have two lists to merge */ 311 /* if q hasn't fallen off end, we have two lists to merge */
312 int qsize = insize; 312 int qsize = insize;
313 313
314 /* now we have two lists; merge them */ 314 /* now we have two lists; merge them */
315 while (psize > 0 || (qsize > 0 && q)) { 315 while ( psize > 0 || (qsize > 0 && q) ) {
316
317 struct dlist_element *e; 316 struct dlist_element *e;
318 317
319 /* decide whether next element of merge comes from p or q */ 318 /* decide whether next element of merge comes from p or q */
320 if (psize == 0) { 319 if ( psize == 0 ) {
321 /* p is empty; e must come from q. */ 320 /* p is empty; e must come from q. */
322 e = q; q = q->next; qsize--; 321 e = q;
323 } else if (qsize == 0 || !q) { 322 q = q->next;
323 qsize--;
324 }
325 else if ( qsize == 0 || !q ) {
324 /* q is empty; e must come from p. */ 326 /* q is empty; e must come from p. */
325 e = p; p = p->next; psize--; 327 e = p;
326 } else if (p->data < q->data) { 328 p = p->next;
329 psize--;
330 }
331 else if ( p->data < q->data ) {
327 /* First element of p is lower ; 332 /* First element of p is lower ;
328 * e must come from p. */ 333 * e must come from p. */
329 e = p; p = p->next; psize--; 334 e = p;
330 } else { 335 p = p->next;
336 psize--;
337 }
338 else {
331 /* First element of q is lower; e must come from q. */ 339 /* First element of q is lower; e must come from q. */
332 e = q; q = q->next; qsize--; 340 e = q;
341 q = q->next;
342 qsize--;
333 } 343 }
334 344
335 /* add the next element to the merged list */ 345 /* add the next element to the merged list */
336 if (list->tail) { 346 if ( list->tail ) {
337 list->tail->next = e; 347 list->tail->next = e;
338 } else { 348 }
349 else {
339 list->head = e; 350 list->head = e;
340 } 351 }
341 e->prev = list->tail; 352 e->prev = list->tail;
342 list->tail = e; 353 list->tail = e;
343 } 354 }
344 355
@@ -348,8 +359,8 @@ dlist_sort_xxx(struct dlist *list)
348 list->tail->next = NULL; 359 list->tail->next = NULL;
349 360
350 /* If we have done only one merge, we're finished. */ 361 /* If we have done only one merge, we're finished. */
351 if (nmerges <= 1) /* allow for nmerges==0, the empty list case */ 362 if ( nmerges <= 1 ) /* allow for nmerges==0, the empty list case */
352 return; // list; 363 return; // list;
353 364
354 /* Otherwise repeat, merging lists twice the size */ 365 /* Otherwise repeat, merging lists twice the size */
355 insize *= 2; 366 insize *= 2;
@@ -364,31 +375,29 @@ dlist_merge(struct dlist *list1, struct dlist *list2)
364 *e1 = list1->head, 375 *e1 = list1->head,
365 *e2 = list2->head; 376 *e2 = list2->head;
366 377
367 while ( e1 != NULL && e2 != NULL ) // Solange in e1 UND e2 Elemente sind... 378 while ( e1 != NULL && e2 != NULL ) // Solange in e1 UND e2 Elemente sind...
368 { 379 {
369 if ( e1->data < e2->data ) 380 if ( e1->data < e2->data ) {
370 {
371 e1->prev = cur; 381 e1->prev = cur;
372 if ( cur != NULL ) 382 if ( cur != NULL )
373 cur->next = e1; 383 cur->next = e1;
374 else 384 else
375 head = e1; 385 head = e1;
376 cur = e1; 386 cur = e1;
377 e1 = e1->next; 387 e1 = e1->next;
378 } 388 }
379 else 389 else {
380 {
381 e2->prev = cur; 390 e2->prev = cur;
382 if ( cur != NULL ) 391 if ( cur != NULL )
383 cur->next = e2; 392 cur->next = e2;
384 else 393 else
385 head = e2; 394 head = e2;
386 cur = e2; 395 cur = e2;
387 e2 = e2->next; 396 e2 = e2->next;
388 } 397 }
389 } 398 }
390 399
391 if ( e1 != NULL ) // in e1 sind noch Elemente vorhanden! 400 if ( e1 != NULL ) // in e1 sind noch Elemente vorhanden!
392 { 401 {
393 assert(e2 == NULL); 402 assert(e2 == NULL);
394 403
@@ -411,7 +420,7 @@ dlist_merge(struct dlist *list1, struct dlist *list2)
411 else 420 else
412 head = e2; 421 head = e2;
413 422
414 list1->tail = list2->tail; // list2->tail ist das Ende der Liste 423 list1->tail = list2->tail; // list2->tail ist das Ende der Liste
415 } 424 }
416 425
417 // Kopf neu setzen... 426 // Kopf neu setzen...
@@ -428,17 +437,17 @@ dlist_merge(struct dlist *list1, struct dlist *list2)
428struct dlist * 437struct dlist *
429dlist_sort(struct dlist *list) 438dlist_sort(struct dlist *list)
430{ 439{
431 if ( list->head == NULL || list->head->next == NULL ) // Leer oder nur ein Element? => Fertig 440 if ( list->head == NULL || list->head->next == NULL ) // Leer oder nur ein Element? => Fertig
432 return list; 441 return list;
433 442
434 struct dlist_element *slow = list->head, 443 struct dlist_element *slow = list->head,
435 *fast = list->head->next; 444 *fast = list->head->next;
436 445
437 while ( fast != NULL && fast->next != NULL ) 446 while ( fast != NULL && fast->next != NULL )
438 slow = slow->next, fast = fast->next->next; 447 slow = slow->next, fast = fast->next->next;
439 448
440 struct dlist list1 = { .head = list->head, .tail = slow }, 449 struct dlist list1 = { .head = list->head, .tail = slow },
441 list2 = { .head = slow->next, .tail = list->tail }; 450 list2 = { .head = slow->next, .tail = list->tail };
442 451
443 list1.tail->next = list2.head->prev = NULL; 452 list1.tail->next = list2.head->prev = NULL;
444 453
@@ -450,7 +459,8 @@ dlist_sort(struct dlist *list)
450 return list; 459 return list;
451} 460}
452 461
453void merge_test(void) 462void
463merge_test(void)
454{ 464{
455 struct dlist l1, l2; 465 struct dlist l1, l2;
456 466
@@ -472,9 +482,15 @@ void merge_test(void)
472 482
473 struct dlist_element *cur; 483 struct dlist_element *cur;
474 for ( cur = ptr->head; cur; cur = cur->next ) { 484 for ( cur = ptr->head; cur; cur = cur->next ) {
475 if ( cur->prev ) printf("%4d", cur->prev->data); else printf("xxx "); 485 if ( cur->prev )
486 printf("%4d", cur->prev->data);
487 else
488 printf("xxx ");
476 printf("%4d", cur->data); 489 printf("%4d", cur->data);
477 if ( cur->next ) printf("%4d", cur->next->data); else printf(" xxx"); 490 if ( cur->next )
491 printf("%4d", cur->next->data);
492 else
493 printf(" xxx");
478 494
479 puts(""); 495 puts("");
480 } 496 }
@@ -483,7 +499,8 @@ void merge_test(void)
483 dlist_free(&l2); 499 dlist_free(&l2);
484} 500}
485 501
486void ls() 502void
503ls()
487{ 504{
488 struct dlist list; 505 struct dlist list;
489 506
@@ -498,14 +515,13 @@ void ls()
498 dlist_sort(&list); 515 dlist_sort(&list);
499 clock_t ende = clock(); 516 clock_t ende = clock();
500 517
501 printf("Dauer: %.3fsec\n", ((double) ende-start)/CLOCKS_PER_SEC); 518 printf("Dauer: %.3fsec\n", ((double) ende - start) / CLOCKS_PER_SEC);
502 //print_list("Sortiert:", &list); 519 //print_list("Sortiert:", &list);
503 //print_list_rev("Sortiert:", &list); 520 //print_list_rev("Sortiert:", &list);
504 521
505 dlist_free(&list); 522 dlist_free(&list);
506} 523}
507 524
508
509int 525int
510main(void) 526main(void)
511{ 527{
@@ -536,4 +552,3 @@ main(void)
536 return EXIT_SUCCESS; 552 return EXIT_SUCCESS;
537#endif 553#endif
538} 554}
539