Re: Quicksort
- From: user923005 <dcorbit@xxxxxxxxx>
- Date: Tue, 8 Jan 2008 16:50:50 -0800 (PST)
On Jan 8, 2:56 pm, "cr88192" <cr88...@xxxxxxxxxxx> wrote:
"user923005" <dcor...@xxxxxxxxx> wrote in message
news:5888dd6d-f82f-47a9-8f32-ca1cc08cff9d@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
On Jan 8, 4:29am, "cr88192" <cr88...@xxxxxxxxxxx> wrote:> <robertwess...@xxxxxxxxx> wrote in message
[snip]
<
Note: I am not sure about proper quoting here, since the post I am
replying to appeared to be missing a level of quote indicators.
Outlook Express is giving me crap...
me being too lazy to switch to a different newsreader, quote things as
above.
I did not innovate this style of quotes though, but have seen similar
before.
Besides, a heapsort is hardly complex to implement. Frankly, it would
probably be better if heapsort was most people's first choice - it's
only a bit more complex than quicksort in its basic form, and unlike
quicksort, it's perfectly usable in its basic form, all while only
being a factor of two, or so, slower. Once you add all the required
frou-frou to make quicksort usable, it's just as complex, if not more
so.
not really...
<
#include <cstdlib>
/* Adapted from Pete Filander's C version: */
/*http://www.mindspring.com/~pfilandr/C/e_driver/e_sort.c*/
template < class e_type >
void hsortm(e_type * array, size_t nmemb)
{
size_t p,
child,
parent;
e_type temp;
if (nmemb > 1) {
p = --nmemb / 2;
do {
parent = (p);
child = parent * 2;
temp = (array)[parent];
while ((nmemb) - parent > parent) {
if ((*((array) + child + 1) > *((array) + child))) {
++child;
}
if ((*((array) + child) > *(&temp))) {
(array)[parent] = (array)[child];
parent = child;
child *= 2;
} else {
break;
}
}
if ((nmemb) == child && (*((array) + child) > *(&temp))) {
(array)[parent] = (array)[child];
parent = child;
}
(array)[parent] = temp;
} while (p-- != 0);
((void) (*(&temp) = *(array), *(array) = *(array + nmemb),
*(array + nmemb) = *(&temp)));
while (--nmemb != 0) {
parent = (0);
child = parent * 2;
temp = (array)[parent];
while ((nmemb) - parent > parent) {
if ((*((array) + child + 1) > *((array) + child))) {
++child;
}
if ((*((array) + child) > *(&temp))) {
(array)[parent] = (array)[child];
parent = child;
child *= 2;
} else {
break;
}
}
if ((nmemb) == child && (*((array) + child) > *(&temp))) {
(array)[parent] = (array)[child];
parent = child;
}
(array)[parent] = temp;
((void) (*(&temp) = *(array), *(array) = *(array + nmemb),
*(array + nmemb) = *(&temp)));
}
}
}
you are claiming this is, simpler?...
and, in this example, you even have templates on your side...
even as such, note the number of compound expressions and pointer
operations.
actually, many of these could be changed to array indices, and many of these
pointer operations are useless, I have no idea why this is written this
way...
for fairness, I will take the example given, and clean it up:
template<class e_type> void hsortm(e_type *array, size_t nmemb)
{
size_t p, child, parent;
e_type temp;
if (nmemb>1)
{
p=(--nmemb)/2;
do {
parent=p;
child=parent * 2;
temp=array[parent];
while ((nmemb-parent)>parent)
{
if (array[child+1]>array[child]) child++;
if (array[child]>temp)
{
array[parent]=array[child];
parent=child;
child*=2;
}else break;
}
if ((nmemb==child) && (array[child]>temp))
{
array[parent]=array[child];
parent=child;
}
array[parent]=temp;
} while (p--);
temp=array[0];
array[0]=array[nmemb];
array[nmemb]=temp;
while (--nmemb)
{
parent=0;
child=parent*2;
temp=array[parent];
while ((nmemb-parent)>parent)
{
if (array[child+1]>array[child]) child++;
if (array[child]>temp)
{
array[parent]=array[child];
parent=child;
child*=2;
} else break;
}
if ((nmemb==child) && (array[child]>temp))
{
array[parent]=array[child];
parent=child;
}
array[parent]=temp;
temp=array[0];
array[0]=array[nmemb];
array[nmemb]=temp;
}
}
}
still slightly more complicated than quicksort IMO, but IMO now somewhat
less horrid...
here is the algo of mine from before, adapted for an array of integers:
void Swap(int *arr, int i, int j)
{
int k;
if(i==j)return;
k=arr[i]; arr[i]=arr[j]; arr[j]=k;
}
void Sort(int *arr, int base, int lim)
{
static int depth=0;
int mp;
int low, mid, high;
int i, j;
if((lim-base)<2)return;
depth++;
if(depth>=32) //bad case, use selection sort
{ for(i=base; i<lim; i++)for(j=i+1; j<lim; j++)
if(arr[j]<arr[i])Swap(arr, i, j);
return; }
low=base; high=lim; mid=(low+high)/2;
mp=arr[mid];
i=low;
while(i<high)
{
if(arr[i]<mp) { Swap(arr, low++, i++); continue; }
if(arr[i]>mp) { Swap(--high, i); continue; }
i++;
}
Sort(base, low);
Sort(high, lim);
depth--;
}
and here is how it would look incorporating cocktail sort as a fallback:
void Sort(int *arr, int base, int lim)
{
static int depth=0;
int mp;
int low, mid, high;
int i, j;
if((lim-base)<2)return;
depth++;
if(depth>=32) //bad case, use selection sort
{
j=1; while(j)
{
j=0; lim--;
for(i=base; i<lim; i++)
if(arr[i+1]<arr[i]) { Swap(i, i+1); j++; }
for(i=lim; i>base; i--)
if(arr[i]<arr[i-1]) { Swap(i, i-1); j++; }
base++;
}
return;
}
low=base; high=lim; mid=(low+high)/2;
mp=arr[mid];
i=low;
while(i<high)
{
if(arr[i]<mp) { Swap(arr, low++, i++); continue; }
if(arr[i]>mp) { Swap(--high, i); continue; }
i++;
}
Sort(base, low);
Sort(high, lim);
depth--;
}- Hide quoted text -
- Show quoted text -
Given the following definition for SWAP, I tried to implement your
sort:
#include <stdlib.h>
#define SWAP(A, B, T) ((void)(*(T) = *(A), *(A) = *(B), *(B) = *(T)))
typedef int e_type;
static void cr88192Sort(e_type * arr, int base, int lim, int
depth)
{
e_type mp;
int low,
mid,
high;
int i,
j;
if ((lim - base) < 2)
return;
depth++;
if (depth >= 32) { // bad case, use selection sort
j = 1;
while (j) {
e_type tmp;
j = 0;
lim--;
for (i = base; i < lim; i++)
if (arr[i + 1] < arr[i]) {
SWAP(&arr[i], &arr[i + 1], &tmp);
j++;
}
for (i = lim; i > base; i--)
if (arr[i] < arr[i - 1]) {
SWAP(&arr[i], &arr[i - 1], &tmp);
j++;
}
base++;
}
return;
}
low = base;
high = lim;
mid = (low + high) / 2;
mp = arr[mid];
i = low;
while (i < high) {
e_type tmp;
if (arr[i] < mp) {
SWAP(&arr[low], &arr[i], &tmp);
low++, i++;
continue;
}
if (arr[i] < mp) {
SWAP(&arr[high], &arr[i], &tmp);
high++;
continue;
}
i++;
}
cr88192Sort(arr, base, low, depth);
cr88192Sort(arr, high, lim, depth);
depth--;
}
void cr88192(e_type * array, size_t nmemb)
{
cr88192Sort(array, 0, nmemb - 1, 0);
}
/*
However, it does not produce properly sorted output.
Can you tell me where I went off?
*/
.
- Follow-Ups:
- Re: Quicksort
- From: cr88192
- Re: Quicksort
- References:
- Quicksort
- From: Roman Töngi
- Re: Quicksort
- From: Adak
- Re: Quicksort
- From: robertwessel2@xxxxxxxxx
- Re: Quicksort
- From: cr88192
- Re: Quicksort
- From: robertwessel2@xxxxxxxxx
- Re: Quicksort
- From: cr88192
- Re: Quicksort
- From: user923005
- Re: Quicksort
- From: cr88192
- Quicksort
- Prev by Date: Re: Article on Herbert Schildt, author of C Unleashed, repaired on wikipedia
- Next by Date: Re: Quicksort
- Previous by thread: Re: Quicksort
- Next by thread: Re: Quicksort
- Index(es):
Relevant Pages
|