ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

llmosrt.c
Go to the documentation of this file.
00001 /* $Id: llmosrt.c 51374 2011-04-17 09:50:07Z mkupfer $ */
00002 /* A Linked-List Memory Sort
00003    by Philip J. Erdelsky
00004    pje@acm.org
00005    http://www.alumni.caltech.edu/~pje/
00006 */
00007 
00008 /* According to his website, this file was released into the public domain by Phillip J. Erdelsky */
00009 
00010 
00011 #include <stdio.h>
00012 
00013 void *sort_linked_list(void *p, unsigned index, int (*compare)(void *, void *))
00014 {
00015   unsigned base;
00016   unsigned long block_size;
00017 
00018   struct record
00019   {
00020     struct record *next[1];
00021     /* other members not directly accessed by this function */
00022   };
00023 
00024   struct tape
00025   {
00026     struct record *first, *last;
00027     unsigned long count;
00028   } tape[4];
00029 
00030   /* Distribute the records alternately to tape[0] and tape[1]. */
00031 
00032   tape[0].count = tape[1].count = 0L;
00033   tape[0].first = NULL;
00034   base = 0;
00035   while (p != NULL)
00036   {
00037     struct record *next = ((struct record *)p)->next[index];
00038     ((struct record *)p)->next[index] = tape[base].first;
00039     tape[base].first = ((struct record *)p);
00040     tape[base].count++;
00041     p = next;
00042     base ^= 1;
00043   }
00044 
00045   /* If the list is empty or contains only a single record, then */
00046   /* tape[1].count == 0L and this part is vacuous.               */
00047 
00048   for (base = 0, block_size = 1L; tape[base+1].count != 0L;
00049     base ^= 2, block_size <<= 1)
00050   {
00051     int dest;
00052     struct tape *tape0, *tape1;
00053     tape0 = tape + base;
00054     tape1 = tape + base + 1;
00055     dest = base ^ 2;
00056     tape[dest].count = tape[dest+1].count = 0;
00057     for (; tape0->count != 0; dest ^= 1)
00058     {
00059       unsigned long n0, n1;
00060       struct tape *output_tape = tape + dest;
00061       n0 = n1 = block_size;
00062       while (1)
00063       {
00064         struct record *chosen_record;
00065         struct tape *chosen_tape;
00066         if (n0 == 0 || tape0->count == 0)
00067         {
00068           if (n1 == 0 || tape1->count == 0)
00069             break;
00070           chosen_tape = tape1;
00071           n1--;
00072         }
00073         else if (n1 == 0 || tape1->count == 0)
00074         {
00075           chosen_tape = tape0;
00076           n0--;
00077         }
00078         else if ((*compare)(tape0->first, tape1->first) > 0)
00079         {
00080           chosen_tape = tape1;
00081           n1--;
00082         }
00083         else
00084         {
00085           chosen_tape = tape0;
00086           n0--;
00087         }
00088         chosen_tape->count--;
00089         chosen_record = chosen_tape->first;
00090         chosen_tape->first = chosen_record->next[index];
00091         if (output_tape->count == 0)
00092           output_tape->first = chosen_record;
00093         else
00094           output_tape->last->next[index] = chosen_record;
00095         output_tape->last = chosen_record;
00096         output_tape->count++;
00097       }
00098     }
00099   }
00100 
00101   if (tape[base].count > 1L)
00102     tape[base].last->next[index] = NULL;
00103   return tape[base].first;
00104 }
00105 
00106 /* EOF */

Generated on Sat May 26 2012 04:36:35 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.