<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: Quick Sort</title>
	<atom:link href="http://programmingpraxis.com/2009/11/03/quick-sort/feed/" rel="self" type="application/rss+xml" />
	<link>http://programmingpraxis.com/2009/11/03/quick-sort/</link>
	<description>A collection of etudes, updated weekly, for the education and enjoyment of the savvy programmer</description>
	<lastBuildDate>Mon, 28 May 2012 03:30:45 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: Vikas Tandi</title>
		<link>http://programmingpraxis.com/2009/11/03/quick-sort/#comment-2942</link>
		<dc:creator><![CDATA[Vikas Tandi]]></dc:creator>
		<pubDate>Thu, 28 Apr 2011 13:24:43 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=1576#comment-2942</guid>
		<description><![CDATA[generating random every is very costly and slows down the algorithm considerably.
I have used the median of three elements instead.
Here is my c implementation
[sourcecode lang=&quot;cpp&quot;]
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;

#define M 10

void insertion_sort(int arr[], int left, int right);
static void swap(int arr[], int i, int j);
static int partition(int arr[], int left, int right);
static void quicksort_imp(int arr[], int left, int right);

/* assume presence of two artificial keys arr[0] = -ve infinity
	and arr[n+1] = +ve infinity such that arr[0] &lt;= arr[i] &lt;= arr[n+1]
	for 1 &lt;= i &lt;= n */
void quicksort(int arr[], int left, int right)
{
	/* if array size is small or equal to M than
		sort it directly by straight insertion sort */
	if((right-left-1) &gt; M)
		quicksort_imp(arr, left+1, right-1);

	if(M &gt; 1)
		insertion_sort(arr, left+1, right-1);
}

static void quicksort_imp(int arr[], int left, int right)
{
	int pivot, mid;

	/* select pivot element */
	mid = (left + right)/2;
	pivot = (left + mid + right)/3;

	/* swap pivot element with the first element */
	swap(arr, left, pivot);

	/* partition the array */
	pivot = partition(arr, left, right);

	/* right subfile is greater than or equal to left subfile and both subfiles are greater than M */
	if((right - pivot) &gt;= (pivot - left)	&amp;&amp;
		(right - pivot) &gt; M					&amp;&amp;
		(pivot - left) &gt; M)
	{
		/* sort the smaller subfile first to ensure that the stack size doesn&#039;t grow
		more than log N */
		quicksort_imp(arr, left, pivot-1);
		quicksort_imp(arr, pivot+1, right);
	}

	/* left subfile is greater than right subfile and also both subfiles are greater than M */
	if((pivot - left) &gt; (right - pivot) 	&amp;&amp;
		(right - pivot) &gt; M					&amp;&amp;
		(pivot - left) &gt; M)
	{
		/* sort the smaller subfile first to ensure that the stack size doesn&#039;t grow
		more than log N */
		quicksort_imp(arr, pivot+1, right);
		quicksort_imp(arr, left, pivot-1);
	}

	/* right subfile is greater than left subfile, right subfile is greater than M
		and left subfiles is less than or equal to M */
	if((right - pivot) &gt; (pivot - left)	&amp;&amp;
		(right - pivot) &gt; M				&amp;&amp;
		(pivot - left) &lt;= M)
	{
		quicksort_imp(arr, pivot+1, right);
	}

	/* left subfile is greater than right subfile, left subfile is greater than M
		and right subfiles is less than or equal to M */
	if((pivot - left) &gt; (right - pivot)	&amp;&amp;
		(pivot - left) &gt; M				&amp;&amp;
		(right - pivot) &lt;= M)
	{
		quicksort_imp(arr, left, pivot-1);
	}

	/* if both subfile are smaller than M, unwind the stack */
}

static int partition(int arr[], int left, int right)
{
	int i, j, key;

	/* partition the element */
	for(i = left, j = right+1, key = arr[left]; ;)
	{
		/* compare key with arr[i] */
		for(i = i+1; arr[i] &lt; key; i++);		/* the loop must terminate with i &lt;= j as arr[j] &gt;= key */

		/* compare key with arr[j] */
		for(j = j-1; arr[j] &gt; key; j--);		/* the loop must terminate with j &gt;= (i-1) as arr[i-1] &lt;= key */

		if(j &lt;= i)	/* end of partition */
		{
			swap(arr, left, j);
			break;
		}
		swap(arr, i, j);
	}

	return j;
}

void insertion_sort(int arr[], int left, int right)
{
	int i, min;

	/* move smallest key to left end */
	for(i = left+1, min = left; i &lt;= right; i++)
		if(arr[min] &gt; arr[i])
			min = i;

	swap(arr, left, min);

	for(i = left+1; i &lt;= right; i++)
	{
		int j, key;

		for(j = i-1, key = arr[i]; arr[j] &gt; key; j--)
				arr[j+1] = arr[j];

		arr[j+1] = key;
	}
}

static void swap(int arr[], int i, int j)
{
	int t;
	t = arr[i];
	arr[i] = arr[j];
	arr[j] = t;
}
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>generating random every is very costly and slows down the algorithm considerably.<br />
I have used the median of three elements instead.<br />
Here is my c implementation</p>
<pre class="brush: cpp;">
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;

#define M 10

void insertion_sort(int arr[], int left, int right);
static void swap(int arr[], int i, int j);
static int partition(int arr[], int left, int right);
static void quicksort_imp(int arr[], int left, int right);

/* assume presence of two artificial keys arr[0] = -ve infinity
	and arr[n+1] = +ve infinity such that arr[0] &lt;= arr[i] &lt;= arr[n+1]
	for 1 &lt;= i &lt;= n */
void quicksort(int arr[], int left, int right)
{
	/* if array size is small or equal to M than
		sort it directly by straight insertion sort */
	if((right-left-1) &gt; M)
		quicksort_imp(arr, left+1, right-1);

	if(M &gt; 1)
		insertion_sort(arr, left+1, right-1);
}

static void quicksort_imp(int arr[], int left, int right)
{
	int pivot, mid;

	/* select pivot element */
	mid = (left + right)/2;
	pivot = (left + mid + right)/3;

	/* swap pivot element with the first element */
	swap(arr, left, pivot);

	/* partition the array */
	pivot = partition(arr, left, right);

	/* right subfile is greater than or equal to left subfile and both subfiles are greater than M */
	if((right - pivot) &gt;= (pivot - left)	&amp;&amp;
		(right - pivot) &gt; M					&amp;&amp;
		(pivot - left) &gt; M)
	{
		/* sort the smaller subfile first to ensure that the stack size doesn't grow
		more than log N */
		quicksort_imp(arr, left, pivot-1);
		quicksort_imp(arr, pivot+1, right);
	}

	/* left subfile is greater than right subfile and also both subfiles are greater than M */
	if((pivot - left) &gt; (right - pivot) 	&amp;&amp;
		(right - pivot) &gt; M					&amp;&amp;
		(pivot - left) &gt; M)
	{
		/* sort the smaller subfile first to ensure that the stack size doesn't grow
		more than log N */
		quicksort_imp(arr, pivot+1, right);
		quicksort_imp(arr, left, pivot-1);
	}

	/* right subfile is greater than left subfile, right subfile is greater than M
		and left subfiles is less than or equal to M */
	if((right - pivot) &gt; (pivot - left)	&amp;&amp;
		(right - pivot) &gt; M				&amp;&amp;
		(pivot - left) &lt;= M)
	{
		quicksort_imp(arr, pivot+1, right);
	}

	/* left subfile is greater than right subfile, left subfile is greater than M
		and right subfiles is less than or equal to M */
	if((pivot - left) &gt; (right - pivot)	&amp;&amp;
		(pivot - left) &gt; M				&amp;&amp;
		(right - pivot) &lt;= M)
	{
		quicksort_imp(arr, left, pivot-1);
	}

	/* if both subfile are smaller than M, unwind the stack */
}

static int partition(int arr[], int left, int right)
{
	int i, j, key;

	/* partition the element */
	for(i = left, j = right+1, key = arr[left]; ;)
	{
		/* compare key with arr[i] */
		for(i = i+1; arr[i] &lt; key; i++);		/* the loop must terminate with i &lt;= j as arr[j] &gt;= key */

		/* compare key with arr[j] */
		for(j = j-1; arr[j] &gt; key; j--);		/* the loop must terminate with j &gt;= (i-1) as arr[i-1] &lt;= key */

		if(j &lt;= i)	/* end of partition */
		{
			swap(arr, left, j);
			break;
		}
		swap(arr, i, j);
	}

	return j;
}

void insertion_sort(int arr[], int left, int right)
{
	int i, min;

	/* move smallest key to left end */
	for(i = left+1, min = left; i &lt;= right; i++)
		if(arr[min] &gt; arr[i])
			min = i;

	swap(arr, left, min);

	for(i = left+1; i &lt;= right; i++)
	{
		int j, key;

		for(j = i-1, key = arr[i]; arr[j] &gt; key; j--)
				arr[j+1] = arr[j];

		arr[j+1] = key;
	}
}

static void swap(int arr[], int i, int j)
{
	int t;
	t = arr[i];
	arr[i] = arr[j];
	arr[j] = t;
}
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jebb</title>
		<link>http://programmingpraxis.com/2009/11/03/quick-sort/#comment-1030</link>
		<dc:creator><![CDATA[Jebb]]></dc:creator>
		<pubDate>Thu, 18 Feb 2010 23:52:21 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=1576#comment-1030</guid>
		<description><![CDATA[Ongoing experimentations in C. I&#039;d implemented an integer version of this a few months ago, and I just went back and generalized it now I&#039;ve learned how function pointers and (void *) passing works.
[sourcecode lang=&quot;cpp&quot;]
static int swap(void *el1, void *el2, int elemSize)
{
    void *buffer;
    buffer = (void *)malloc(elemSize * sizeof(char));
    assert(buffer);
    memcpy(buffer, el1, elemSize);
    memcpy(el1, el2, elemSize);
    memcpy(el2, buffer, elemSize);
    free(buffer);
}

static int partition(void *base, int length, int elemSize, void *pivot,
                int (*cmpFunc)(void *, void *)) 
{
int i, newIndex;
    void *elt1, *elt2, *lastElt;
    lastElt = (char *)base + (length - 1) * elemSize;
    swap(pivot, lastElt, elemSize); //Move the pivot out of the way
    newIndex = 0;
    elt1 = base;
    for (i = 0; i &lt; length - 1; i++) {  //We&#039;re storing the pivot at the end!!!
        elt2 = (char *)base + i * elemSize;
        if (cmpFunc(lastElt, elt2) &lt; 0) {
            swap(elt1, elt2, elemSize);
            newIndex++;
            elt1 = (char*)base + newIndex * elemSize;
        }   
    }   
    /*Now we only need to re-insert the pivot (which we&#039;ve stored at lastElt)
    *in the array at the proper index
    *With the numbering used, newIndex is now the index of the first element
    *&quot;larger&quot; than the pivot
    *elt1 is still the array element of index newIndex*/
    swap(lastElt, elt1, elemSize);
    return newIndex;
}

int quisort(void *base, int length, int elemSize, int (*cmpFunc)(void *, void *)) 
{
    int pivotNewIndex;
    void *pivot, *base2;
    if (length &gt; 1) {
        srand(time(0));
        pivot = (char *)base + (rand() % length) * elemSize;
        pivotNewIndex = partition(base, length, elemSize, pivot, cmpFunc);
        base2 = (char *)base + (pivotNewIndex + 1) * elemSize;
        quisort(base, pivotNewIndex, elemSize, cmpFunc);
        quisort(base2, length - pivotNewIndex - 1, elemSize, cmpFunc);
    }   
    return 0;
}[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>Ongoing experimentations in C. I&#8217;d implemented an integer version of this a few months ago, and I just went back and generalized it now I&#8217;ve learned how function pointers and (void *) passing works.</p>
<pre class="brush: cpp;">
static int swap(void *el1, void *el2, int elemSize)
{
    void *buffer;
    buffer = (void *)malloc(elemSize * sizeof(char));
    assert(buffer);
    memcpy(buffer, el1, elemSize);
    memcpy(el1, el2, elemSize);
    memcpy(el2, buffer, elemSize);
    free(buffer);
}

static int partition(void *base, int length, int elemSize, void *pivot,
                int (*cmpFunc)(void *, void *)) 
{
int i, newIndex;
    void *elt1, *elt2, *lastElt;
    lastElt = (char *)base + (length - 1) * elemSize;
    swap(pivot, lastElt, elemSize); //Move the pivot out of the way
    newIndex = 0;
    elt1 = base;
    for (i = 0; i &lt; length - 1; i++) {  //We're storing the pivot at the end!!!
        elt2 = (char *)base + i * elemSize;
        if (cmpFunc(lastElt, elt2) &lt; 0) {
            swap(elt1, elt2, elemSize);
            newIndex++;
            elt1 = (char*)base + newIndex * elemSize;
        }   
    }   
    /*Now we only need to re-insert the pivot (which we've stored at lastElt)
    *in the array at the proper index
    *With the numbering used, newIndex is now the index of the first element
    *&quot;larger&quot; than the pivot
    *elt1 is still the array element of index newIndex*/
    swap(lastElt, elt1, elemSize);
    return newIndex;
}

int quisort(void *base, int length, int elemSize, int (*cmpFunc)(void *, void *)) 
{
    int pivotNewIndex;
    void *pivot, *base2;
    if (length &gt; 1) {
        srand(time(0));
        pivot = (char *)base + (rand() % length) * elemSize;
        pivotNewIndex = partition(base, length, elemSize, pivot, cmpFunc);
        base2 = (char *)base + (pivotNewIndex + 1) * elemSize;
        quisort(base, pivotNewIndex, elemSize, cmpFunc);
        quisort(base2, length - pivotNewIndex - 1, elemSize, cmpFunc);
    }   
    return 0;
}</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joe Doliner</title>
		<link>http://programmingpraxis.com/2009/11/03/quick-sort/#comment-756</link>
		<dc:creator><![CDATA[Joe Doliner]]></dc:creator>
		<pubDate>Tue, 10 Nov 2009 08:06:24 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=1576#comment-756</guid>
		<description><![CDATA[Whoops messed up the formatting.
Quicky python solution:
[sourcecode lang=&quot;python&quot;]
def qsort(A):
	if (len(A) &lt; 2):
		return A
	else:
		return qsort(filter(lambda x: x &lt;= A[0], A[1:])) + [A[0]] + qsort(filter(lambda x: x &gt; A[0], A[1:]))
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>Whoops messed up the formatting.<br />
Quicky python solution:</p>
<pre class="brush: python;">
def qsort(A):
	if (len(A) &lt; 2):
		return A
	else:
		return qsort(filter(lambda x: x &lt;= A[0], A[1:])) + [A[0]] + qsort(filter(lambda x: x &gt; A[0], A[1:]))
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joe Doliner</title>
		<link>http://programmingpraxis.com/2009/11/03/quick-sort/#comment-755</link>
		<dc:creator><![CDATA[Joe Doliner]]></dc:creator>
		<pubDate>Tue, 10 Nov 2009 08:05:13 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=1576#comment-755</guid>
		<description><![CDATA[Quicky python solution:
[source lang=&quot;python&quot;][/source]
def qsort(A):
	if (len(A) &lt; 2):
		return A
	else:
		return qsort(filter(lambda x: x  A[0], A[1:]))
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>Quicky python solution:</p>
<p>def qsort(A):<br />
	if (len(A) &lt; 2):<br />
		return A<br />
	else:<br />
		return qsort(filter(lambda x: x  A[0], A[1:]))<br />
[/sourcecode]</p>
]]></content:encoded>
	</item>
</channel>
</rss>

