Advertisement

Fastest QuickSort?

Started by May 06, 2001 09:02 PM
2 comments, last by Slingblade 23 years, 9 months ago
Does anyone have a quick, small Quicksort function? This is all I came up with:

void QuickSort(int list[], int start, int end)
{
	if (start >= end) // base case (list is sorted)
		return;


	// choose a pivot point
	int pivot = list[(start+end)/2];
	int leftbound = start;
	int rightbound = end;


	while (leftbound <= rightbound)
	{
		// find first element that is greater than pivot on left side
		while ((leftbound < end) && (list[leftbound] < pivot))
			leftbound++;


		// find first element that is smaller than pivot on right side
		while ((rightbound > start) && (list[rightbound] > pivot))
			rightbound--;


		// swap if indexes haven't crossed
		if (leftbound <= rightbound)
		{
			int temp = list[leftbound];
			list[leftbound] = list[rightbound];
			list[rightbound] = temp;

			leftbound++;
			rightbound--;
		}
	}


	QuickSort(list, start, rightbound); // sort left
	QuickSort(list, leftbound, end); // sort right
}
  
Edited by - Slingblade on May 6, 2001 10:03:52 PM
Some folks call it a sling blade...I call it a keiser blade.
This is the one I use (I didn''t write it, but it is incredibly fast compared to MSVC''s or Borland''s standard qsort):
  #include <stddef.h>#define InitSwap(a, es) SwapType = (a-(char *)0 | es) % sizeof(long) ? 2 : es > sizeof(long);#define SwapCode(TYPE, parmi, parmj, n) { \  register TYPE *pi = (TYPE *) parmi; \  register TYPE *pj = (TYPE *) parmj; \  do { \    register TYPE t = *pi; \    *pi++ = *pj; \    *pj++ = t; \  } while((n -= sizeof(TYPE)) > 0); \}#define Swap(a, b) \  if(SwapType == 0) { \    t = *(long *)(a) = *(long *)(b); \    *(long *)(a) = *(long*)(b); \    *(long *)(b) = t; \  } else SwapFunc(a, b, es, SwapType)#define InitPV(pv, pm) \  if(SwapType != 0) { \    pv = a; \    Swap(pv, pm); \  } else { \    pv = (char *) &v \    *(long *)pv = *(long *)pm; \  }#define VecSwap(a, b, n) if (n > 0) SwapFunc(a, b, n, SwapType)#define min(x, y) ((x)<=(y) ? (x) : (y))static void SwapFunc(char *a, char *b, unsigned int n, int SwapType) {  if(SwapType <= 1) {    SwapCode(long, a, b, n);  } else {    SwapCode(char, a, b, n);  }}static char *med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *)) {  return cmp(a, b) < 0 ?            (cmp(b, c) < 0 ? b : cmp(a, c) < 0 ? c : a)          : (cmp(b, c) > 0 ? b : cmp(a, c) > 0 ? c : a);}void fast_qsort(char *a, unsigned int n, unsigned int es, int (*cmp)(const void *a,const void *b)) {  char *pa, *pb, *pc, *pd, *pl, *pm, *pn, *pv;  int r, SwapType;  long t, v;  unsigned int s;  InitSwap(a, es);  if(n < 7) { /* Insertion sort on smaller arrays */    for(pm = a+es; pm < a + n*es; pm += es) {      for(pl = pm; pl > a && cmp(pl-es, pl) > 0; pl -= es) {        Swap(pl, pl-es);      }    }    return;  }  pm = a + (n/2)*es; /* Small arrays, middle element */  if(n > 7) {    pl = a;    pn = ((n-1)*es)+a;    if(n > 40) { /* Big arrays, pseudomedian of 9 */      s = (n/8)*es;      pl = med3(pl, pl+s, pl+2*s, cmp);      pm = med3(pm-s, pm, pm+s, cmp);      pn = med3(pn-(2*s), pn-s, pn, cmp);    }    pm = med3(pl, pm, pn, cmp); /* Mid-size, med of 3 */  }  InitPV(pv, pm); /* pv points to partition value */  pa = pb = a;  pc = pd = ((n-1)*es)+a;  for( ; ; ) {    while(pb <= pc && (r = cmp(pb, pv)) <= 0) {      if(r == 0) {        Swap(pa, pb);        pa += es;      }      pb += es;    }    while(pv <= pc && (r = cmp(pc, pv)) >= 0) {      if(r == 0) {        Swap(pc, pd);        pd -= es;      }      pc -= es;    }    if(pb > pc) break;    Swap(pb, pc);    pb += es;    pc -= es;  }  pn = (n*es)+a;  s = min(pa-a, pb-pa);  VecSwap(a, pb-s, s);  s = min(pd-pc, pn-pd-es);  VecSwap(pb, pn-s, s);  if((s = pb-pa) > es) fast_qsort(a, s/es, es, cmp);  if((s = pd-pc) > es) fast_qsort(pn-s, s/es, es, cmp);}  


Resist Windows XP''s Invasive Production Activation Technology!
http://druidgames.cjb.net/
Advertisement
Well, it got mangled by the source tags, but if you want a copy, I''ll email it to you (complete with the tiny header I wrote for it). Copy/Pasting from IE mangles it even more .

Resist Windows XP''s Invasive Production Activation Technology!
http://druidgames.cjb.net/
Of course, for a small amount of extra memory, you could use the radix sort, which will always be faster than the fast quicksort. But if memory is a real issue, then the fast quicksort is good.

One thing I''d change on that implementation, though, is to run the insertion sort only after the entire quicksorting process is done. I doubt there''d much of an increase in speed, but doing the insertion sorting in one go looks cleaner to me.

This topic is closed to new replies.

Advertisement