Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenllmosrt.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
1.7.6.1
|