listops.c
上传用户:lengbin
上传日期:2010-03-31
资源大小:121k
文件大小:4k
开发平台:

C/C++

  1. /*----------------------------------------------------------------------
  2.   File    : listops.c
  3.   Contents: some special list operations
  4.   Author  : Christian Borgelt
  5.   History : 02.11.2000 file created from file lists.h
  6. ----------------------------------------------------------------------*/
  7. #include <stdio.h>
  8. #include "listops.h"
  9. /*----------------------------------------------------------------------
  10.   Functions
  11. ----------------------------------------------------------------------*/
  12. void* l_sort (void *list, LCMPFN cmpfn, void *data)
  13. {                               /* --- sort a list with mergesort */
  14.   LE *src, *dst;                /* list of source/destination lists */
  15.   LE **end;                     /* end of list of destination lists */
  16.   LE *in1, *in2;                /* input lists for merging */
  17.   LE **out;                     /* output list for merging */
  18.   if (!list) return list;       /* check for an empty list */
  19.   for (src = list; src->succ; ) {
  20.     dst = src; src = src->succ; /* traverse the list and split it */
  21.     dst->succ = NULL;           /* into a list (abused pred ptr.) of */ 
  22.   }                             /* single element lists (succ ptr.) */
  23.   while (src->pred) {           /* while more than one source list */
  24.     end = &dst;                 /* start list of destination lists */
  25.     do {                        /* merge pairs of source lists */
  26.       out = end;                /* start output list (merged input) */
  27.       in1 = src;                /* remove two (one) source list(s) */
  28.       in2 = src->pred;          /* and use them as input for merging */
  29.       if (!in2) {               /* if there is only one source list */
  30.         *end = in1; end = &in1->pred;
  31.         break;                  /* append it to the list of */
  32.       }                         /* output list and abort the loop */
  33.       src = in2->pred;          /* remove lists from list of sources */
  34.       while (1) {               /* source lists merge loop */
  35.         if (cmpfn(in1, in2, data) < 0) {
  36.                                 /* if first list's element is smaller */
  37.           *out = in1;           /* move element to output list, */
  38.           out  = &(in1->succ);  /* advance output pointer and */ 
  39.           in1  = in1->succ;     /* remove element from input list */
  40.           if (!in1) break; }    /* if the list gets empty, abort loop */
  41.         else {                  /* if second list's element is smaller */
  42.           *out = in2;           /* move element to output list, */
  43.           out  = &(in2->succ);  /* advance output pointer and */
  44.           in2  = in2->succ;     /* remove element from input list */
  45.           if (!in2) break;      /* if the list gets empty, abort loop */
  46.         }                       /* (merge input lists into one) */
  47.       }
  48.       if (in1) *out = in1;      /* append remaining elements */
  49.       else     *out = in2;      /* to the output list */
  50.       end = &(*end)->pred;      /* advance destination list pointer */
  51.     } while (src);              /* while there is another source list */
  52.     *end = NULL;                /* terminate destination list */
  53.     src  = dst;                 /* transfer destination list */
  54.   }                             /* to source list and start over */
  55.   for (src->pred = NULL; src->succ; src = src->succ)
  56.     src->succ->pred = src;      /* set predecessor pointers */
  57.   return dst;                   /* return a pointer to the first */
  58. }  /* l_sort() */               /* element of the sorted list */
  59. /*--------------------------------------------------------------------*/
  60. void* l_reverse (void *list)
  61. {                               /* --- reverse a list */
  62.   LE *le = NULL;                /* to traverse the list elements */
  63.   while (list) {                /* while the list is not empty */
  64.     le       = list;            /* get the next list element */
  65.     list     = le->succ;        /* exchange the successor */
  66.     le->succ = le->pred;        /* and the predecessor */
  67.     le->pred = list;            /* of the list element */
  68.   }
  69.   return le;                    /* return a pointer to */
  70. }  /* l_reverse() */            /* the new first element */