<?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: Quicksort in Java</title>
	<atom:link href="http://hobershort.wordpress.com/2008/04/08/quicksort-in-java/feed/" rel="self" type="application/rss+xml" />
	<link>http://hobershort.wordpress.com/2008/04/08/quicksort-in-java/</link>
	<description>Our work is never done!</description>
	<lastBuildDate>Mon, 04 Jan 2010 23:58:13 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: A lament &#171; Zeno&#8217;s Parcel Service</title>
		<link>http://hobershort.wordpress.com/2008/04/08/quicksort-in-java/#comment-397</link>
		<dc:creator>A lament &#171; Zeno&#8217;s Parcel Service</dc:creator>
		<pubDate>Mon, 19 May 2008 06:06:11 +0000</pubDate>
		<guid isPermaLink="false">http://hobershort.wordpress.com/?p=177#comment-397</guid>
		<description>[...] a similar vein, my writing of Quicksort in Java was about clarity and readability rather than pure performance. This is not an efficient [...]</description>
		<content:encoded><![CDATA[<p>[...] a similar vein, my writing of Quicksort in Java was about clarity and readability rather than pure performance. This is not an efficient [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Craig Brown</title>
		<link>http://hobershort.wordpress.com/2008/04/08/quicksort-in-java/#comment-385</link>
		<dc:creator>Craig Brown</dc:creator>
		<pubDate>Fri, 16 May 2008 07:17:53 +0000</pubDate>
		<guid isPermaLink="false">http://hobershort.wordpress.com/?p=177#comment-385</guid>
		<description>I have a stable version of quicksort that uses O(logN) extra space so it is essentially in-place.  Sorting 30,000 elements takes about 5 times longer than ordinary quicksort but 120 times quicker than insertion sort.  It is in VB but you can find it here:

http://www.codeproject.com/KB/recipes/StableQuickSort.aspx?display=Print

The same application also has an in-place version of merge sort that uses O(logN) extra space and runs in a similar time.

Craig</description>
		<content:encoded><![CDATA[<p>I have a stable version of quicksort that uses O(logN) extra space so it is essentially in-place.  Sorting 30,000 elements takes about 5 times longer than ordinary quicksort but 120 times quicker than insertion sort.  It is in VB but you can find it here:</p>
<p><a href="http://www.codeproject.com/KB/recipes/StableQuickSort.aspx?display=Print" rel="nofollow">http://www.codeproject.com/KB/recipes/StableQuickSort.aspx?display=Print</a></p>
<p>The same application also has an in-place version of merge sort that uses O(logN) extra space and runs in a similar time.</p>
<p>Craig</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: fabiopedrosa</title>
		<link>http://hobershort.wordpress.com/2008/04/08/quicksort-in-java/#comment-370</link>
		<dc:creator>fabiopedrosa</dc:creator>
		<pubDate>Thu, 08 May 2008 20:21:54 +0000</pubDate>
		<guid isPermaLink="false">http://hobershort.wordpress.com/?p=177#comment-370</guid>
		<description>You most certainly must learn to take critics. They took time to analyze your code and comment on it, and you can&#039;t even appreciate that?
Haven&#039;t you benefited from them?</description>
		<content:encoded><![CDATA[<p>You most certainly must learn to take critics. They took time to analyze your code and comment on it, and you can&#8217;t even appreciate that?<br />
Haven&#8217;t you benefited from them?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Hober Short</title>
		<link>http://hobershort.wordpress.com/2008/04/08/quicksort-in-java/#comment-345</link>
		<dc:creator>Hober Short</dc:creator>
		<pubDate>Fri, 11 Apr 2008 17:47:56 +0000</pubDate>
		<guid isPermaLink="false">http://hobershort.wordpress.com/?p=177#comment-345</guid>
		<description>Well, hello all you dzoners. I really do appreciate the comments.

I feel I should make a few points. The first is that this is by no means optimal. I just wanted to use it as a vehicle to discuss the Memory/CPU tradeoff. If I had put more time and read more than the Wikipedia article on the sort, I&#039;m sure I could have come up with a more efficient version. This is not something that I would, for example, turn in to my professors.

About &quot;variably-stable&quot; that wasn&#039;t describing any implementation of the sort, that was describing that the general specification of a quicksort meant that it could be implemented either way. It&#039;s not inherently stable or unstable. (Perhaps this is true of all sorts, I&#039;ve not studied many extensively. If you read the post about Python, you&#039;ll see that I started learning this quicksort as a way to avoid learning a lot of sorts, for now.)

You guys are coders far and above my readers or myself, so I&#039;m not surprised you guys picked me apart. I just hope that you boys had a good time.

And tj: the quicksort(), for better or worse, returns the sorted list. You&#039;re not taking it&#039;s return, so of course you&#039;re getting abnormal output.</description>
		<content:encoded><![CDATA[<p>Well, hello all you dzoners. I really do appreciate the comments.</p>
<p>I feel I should make a few points. The first is that this is by no means optimal. I just wanted to use it as a vehicle to discuss the Memory/CPU tradeoff. If I had put more time and read more than the Wikipedia article on the sort, I&#8217;m sure I could have come up with a more efficient version. This is not something that I would, for example, turn in to my professors.</p>
<p>About &#8220;variably-stable&#8221; that wasn&#8217;t describing any implementation of the sort, that was describing that the general specification of a quicksort meant that it could be implemented either way. It&#8217;s not inherently stable or unstable. (Perhaps this is true of all sorts, I&#8217;ve not studied many extensively. If you read the post about Python, you&#8217;ll see that I started learning this quicksort as a way to avoid learning a lot of sorts, for now.)</p>
<p>You guys are coders far and above my readers or myself, so I&#8217;m not surprised you guys picked me apart. I just hope that you boys had a good time.</p>
<p>And tj: the quicksort(), for better or worse, returns the sorted list. You&#8217;re not taking it&#8217;s return, so of course you&#8217;re getting abnormal output.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: tj</title>
		<link>http://hobershort.wordpress.com/2008/04/08/quicksort-in-java/#comment-344</link>
		<dc:creator>tj</dc:creator>
		<pubDate>Fri, 11 Apr 2008 17:04:01 +0000</pubDate>
		<guid isPermaLink="false">http://hobershort.wordpress.com/?p=177#comment-344</guid>
		<description>FYI, your sort doesn&#039;t actually work, e.g.

   int[] arr2 = {2, 1};
   quicksort(arr2);
   System.out.printf(Arrays.toString(arr2)); // [2, 1]</description>
		<content:encoded><![CDATA[<p>FYI, your sort doesn&#8217;t actually work, e.g.</p>
<p>   int[] arr2 = {2, 1};<br />
   quicksort(arr2);<br />
   System.out.printf(Arrays.toString(arr2)); // [2, 1]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Leonel</title>
		<link>http://hobershort.wordpress.com/2008/04/08/quicksort-in-java/#comment-343</link>
		<dc:creator>Leonel</dc:creator>
		<pubDate>Fri, 11 Apr 2008 16:58:07 +0000</pubDate>
		<guid isPermaLink="false">http://hobershort.wordpress.com/?p=177#comment-343</guid>
		<description>Usually, quicksort operates in place: instead of returning a different array and then copying their contents to a new array, you should operate over the elements of the original array.

If not, you will spend a lot of time simply copying information around.

Here&#039;s another version, in less lines of code.

    public void quicksort(int[] array, int first, int last) {
        if (first &gt;= last) return;

        int pivot = array[(first + last) / 2];
        int i1 = first, i2 = last;
        while (i1 &lt; i2) {
            while (i1 &lt; i2 &amp;&amp; array[i1] &lt;= pivot) i1++;
            while (i1   pivot) i2--;
            if (i1 &lt; i2) {
                Integer tmp = array[i1];
                array[i1]   = array[i2];
                array[i2]   = tmp;
            }
        }
        quicksort(array, first, i1 - 1);
        quicksort(array, i1,    last);
    }
    public void quicksort(int[] array) {
        quicksort(array, 0, array.length -1);
    }

Notice that in practice, you will never use this. Use the available sort methods in classes java.util.Arrays and java.util.Collections.</description>
		<content:encoded><![CDATA[<p>Usually, quicksort operates in place: instead of returning a different array and then copying their contents to a new array, you should operate over the elements of the original array.</p>
<p>If not, you will spend a lot of time simply copying information around.</p>
<p>Here&#8217;s another version, in less lines of code.</p>
<p>    public void quicksort(int[] array, int first, int last) {<br />
        if (first &gt;= last) return;</p>
<p>        int pivot = array[(first + last) / 2];<br />
        int i1 = first, i2 = last;<br />
        while (i1 &lt; i2) {<br />
            while (i1 &lt; i2 &amp;&amp; array[i1] &lt;= pivot) i1++;<br />
            while (i1   pivot) i2&#8211;;<br />
            if (i1 &lt; i2) {<br />
                Integer tmp = array[i1];<br />
                array[i1]   = array[i2];<br />
                array[i2]   = tmp;<br />
            }<br />
        }<br />
        quicksort(array, first, i1 &#8211; 1);<br />
        quicksort(array, i1,    last);<br />
    }<br />
    public void quicksort(int[] array) {<br />
        quicksort(array, 0, array.length -1);<br />
    }</p>
<p>Notice that in practice, you will never use this. Use the available sort methods in classes java.util.Arrays and java.util.Collections.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Shadowfiend</title>
		<link>http://hobershort.wordpress.com/2008/04/08/quicksort-in-java/#comment-342</link>
		<dc:creator>Shadowfiend</dc:creator>
		<pubDate>Fri, 11 Apr 2008 16:32:34 +0000</pubDate>
		<guid isPermaLink="false">http://hobershort.wordpress.com/?p=177#comment-342</guid>
		<description>Well, in terms of space efficiency, the best way to go would definitely be to do an in-place quicksort.   It&#039;s a little more convoluted to implement, but that&#039;s fine. Naturally the trade-off here is stability -- the in-place quicksort, because it swaps things around a lot, makes it very difficult to be stable. But the bonus is that you use no additional space. If that&#039;s the main concern, of course.

Concerning using a Vector -- if you set the initial capacity to size of the source list you&#039;re basically allocating an array in memory that is that size. It won&#039;t _need_ to resize, and all you gain is adjusting bounds.

I really think that if stability isn&#039;t a problem, in-place quicksort is the way to go. It really hurts me, conceptually, to allocate full-sized arrays for each side. Naturally it helps that you adjust that size at each recursive step, but still.

As a side note, it&#039;s also a better idea to use ArrayList instead of Vector in general, since Vectors are synchronized and therefore out of step with the rest of Java Collections. ArrayLists can be synchronized using Collections.synchronizedCollection().</description>
		<content:encoded><![CDATA[<p>Well, in terms of space efficiency, the best way to go would definitely be to do an in-place quicksort.   It&#8217;s a little more convoluted to implement, but that&#8217;s fine. Naturally the trade-off here is stability &#8212; the in-place quicksort, because it swaps things around a lot, makes it very difficult to be stable. But the bonus is that you use no additional space. If that&#8217;s the main concern, of course.</p>
<p>Concerning using a Vector &#8212; if you set the initial capacity to size of the source list you&#8217;re basically allocating an array in memory that is that size. It won&#8217;t _need_ to resize, and all you gain is adjusting bounds.</p>
<p>I really think that if stability isn&#8217;t a problem, in-place quicksort is the way to go. It really hurts me, conceptually, to allocate full-sized arrays for each side. Naturally it helps that you adjust that size at each recursive step, but still.</p>
<p>As a side note, it&#8217;s also a better idea to use ArrayList instead of Vector in general, since Vectors are synchronized and therefore out of step with the rest of Java Collections. ArrayLists can be synchronized using Collections.synchronizedCollection().</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Giuca</title>
		<link>http://hobershort.wordpress.com/2008/04/08/quicksort-in-java/#comment-341</link>
		<dc:creator>Matt Giuca</dc:creator>
		<pubDate>Fri, 11 Apr 2008 15:05:35 +0000</pubDate>
		<guid isPermaLink="false">http://hobershort.wordpress.com/?p=177#comment-341</guid>
		<description>Oh hey, and the discussion from the Python blog post about stable sorts:

1. The concept of a &quot;variably stable&quot; sort isn&#039;t really legitimate. What you&#039;re saying is that if your sort is unstable, you can make it stable by sorting on the values after you sort on keys. Well I could do that for any sort.

The fact is that this doesn&#039;t make it stable. Stable doesn&#039;t mean &quot;when I&#039;m done, it&#039;s perfectly sorted&quot;. It means that for sorting lists with duplicate keys, the elements which share keys remain in their original order (relative to each other). In other words, you don&#039;t swap two elements unless you have to.

Quicksort is never stable. (The wiki article says &quot;in efficient implementations&quot; - this means that you can make quicksort stable, but then it won&#039;t be quick!)

2. Why do we care about stable sorts? Well sometimes we do and sometimes we don&#039;t. Usually when humans are looking at the data, they want it to be stable -- simply because it *doesn&#039;t make sense* if the computer reorders data for no reason.

Consider an Excel spreadsheet with a &quot;Gender&quot; column (M or F) and a &quot;Name&quot; column. Now I choose to sort by Gender. When I click sort, I want all the males at the top, then the females. But within those categories, I don&#039;t want to see all the names jumbled up randomly. It would seem weird to me, as a human - why did the computer decide to scramble up all my names? I&#039;d prefer it if it kept the original order except for splitting them into the 2 groups.

Even worse, if I click &quot;sort&quot; on already-sorted data, it would look stupid if it decided to jumble up the data even though it was already sorted.

This is why in some situations it is desirable to have a stable sort. So if I was implementing a spreadsheet, I&#039;d do a merge sort (another algorithm that can be made stable, and is approximately as efficient as quicksort, with various different tradeoffs).</description>
		<content:encoded><![CDATA[<p>Oh hey, and the discussion from the Python blog post about stable sorts:</p>
<p>1. The concept of a &#8220;variably stable&#8221; sort isn&#8217;t really legitimate. What you&#8217;re saying is that if your sort is unstable, you can make it stable by sorting on the values after you sort on keys. Well I could do that for any sort.</p>
<p>The fact is that this doesn&#8217;t make it stable. Stable doesn&#8217;t mean &#8220;when I&#8217;m done, it&#8217;s perfectly sorted&#8221;. It means that for sorting lists with duplicate keys, the elements which share keys remain in their original order (relative to each other). In other words, you don&#8217;t swap two elements unless you have to.</p>
<p>Quicksort is never stable. (The wiki article says &#8220;in efficient implementations&#8221; &#8211; this means that you can make quicksort stable, but then it won&#8217;t be quick!)</p>
<p>2. Why do we care about stable sorts? Well sometimes we do and sometimes we don&#8217;t. Usually when humans are looking at the data, they want it to be stable &#8212; simply because it *doesn&#8217;t make sense* if the computer reorders data for no reason.</p>
<p>Consider an Excel spreadsheet with a &#8220;Gender&#8221; column (M or F) and a &#8220;Name&#8221; column. Now I choose to sort by Gender. When I click sort, I want all the males at the top, then the females. But within those categories, I don&#8217;t want to see all the names jumbled up randomly. It would seem weird to me, as a human &#8211; why did the computer decide to scramble up all my names? I&#8217;d prefer it if it kept the original order except for splitting them into the 2 groups.</p>
<p>Even worse, if I click &#8220;sort&#8221; on already-sorted data, it would look stupid if it decided to jumble up the data even though it was already sorted.</p>
<p>This is why in some situations it is desirable to have a stable sort. So if I was implementing a spreadsheet, I&#8217;d do a merge sort (another algorithm that can be made stable, and is approximately as efficient as quicksort, with various different tradeoffs).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Giuca</title>
		<link>http://hobershort.wordpress.com/2008/04/08/quicksort-in-java/#comment-340</link>
		<dc:creator>Matt Giuca</dc:creator>
		<pubDate>Fri, 11 Apr 2008 14:51:54 +0000</pubDate>
		<guid isPermaLink="false">http://hobershort.wordpress.com/?p=177#comment-340</guid>
		<description>Hi, I have a lot to say (sorry), but I teach algorithms at uni so hear me out :)

It&#039;s a pretty good idea to consider what the performance is if the list is already sorted. This situation comes up quite a bit if you have programs that are always sorting the data. (Especially important is the &quot;almost sorted&quot; case, which might arise if you have a sorted list, and add 1 item to the end, and then re-sort it -- in this case Insertion Sort is way more efficient than Quicksort).

Having said that, using a bubble sort to check if it&#039;s already sorted is a Bad Idea. If you do a full bubble sort, obviously it&#039;ll average out to be much slower than Quicksort. The suggestion to do 1 pass of bubble sort doesn&#039;t make much sense either. It means you&#039;re doing a whole extra pass over the data just for the special case of it being already sorted. You don&#039;t need to make the already-sorted case super fast, just make sure it doesn&#039;t kill your sort (which it won&#039;t in the case of quicksort). Also there&#039;s no point using bubble to pick the pivot.

But there *is* such thing as worst and best pivot - the best pivot is the one which separates the data 50/50. The worst pivot is the minimum or maximum value.

Consider in your code what happens if the list is already sorted - then your pivot selection (intlist[0]) will get the minimum value. Then your quicksort will recurse N times, and take N^2 comparisons to complete - JUST AS BAD AS BUBBLE SORT. So that&#039;s a bad pivot selection.

How to improve pivot selection? If you take a whole pass over the data to pick an optimal pivot (the &quot;bubble sort&quot; suggestion), then you&#039;ll waste as much time picking it as if you had picked the worst possible pivot!! So you can&#039;t just write code to pick the best one.

Ideally, just pick an element from the list at random, or pick the middle element of the list (picking the middle element from the list gives you best performance on an already-sorted list).

As Fabse pointed out, it&#039;s not really necessary to use arrays and manually keep track of their length, as Java has builtin list objects that do that for you. (They keep track of both the full length (called &quot;capacity&quot;) and the length of &quot;good&quot; items (called &quot;size&quot;)). However I would _not_ use a LinkedList. That won&#039;t perform as you expect. I&#039;d use a Vector, and be sure to set its initial capacity to the size of the source list.

Also why do you have 3 lists (less, greater, equal). Consider how many elements are put into the &quot;equal&quot; list. If you have 100 items, roughly distributed from 1 to 100, and a pivot of 50, then there&#039;ll be about 50 items in the &quot;less&quot; list, 50 items in the &quot;greater&quot; list, and 1 item in the &quot;equal&quot; list. So don&#039;t do that. Just have a &quot;less than or equal to&quot; list and a &quot;greater than&quot; list.</description>
		<content:encoded><![CDATA[<p>Hi, I have a lot to say (sorry), but I teach algorithms at uni so hear me out <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>It&#8217;s a pretty good idea to consider what the performance is if the list is already sorted. This situation comes up quite a bit if you have programs that are always sorting the data. (Especially important is the &#8220;almost sorted&#8221; case, which might arise if you have a sorted list, and add 1 item to the end, and then re-sort it &#8212; in this case Insertion Sort is way more efficient than Quicksort).</p>
<p>Having said that, using a bubble sort to check if it&#8217;s already sorted is a Bad Idea. If you do a full bubble sort, obviously it&#8217;ll average out to be much slower than Quicksort. The suggestion to do 1 pass of bubble sort doesn&#8217;t make much sense either. It means you&#8217;re doing a whole extra pass over the data just for the special case of it being already sorted. You don&#8217;t need to make the already-sorted case super fast, just make sure it doesn&#8217;t kill your sort (which it won&#8217;t in the case of quicksort). Also there&#8217;s no point using bubble to pick the pivot.</p>
<p>But there *is* such thing as worst and best pivot &#8211; the best pivot is the one which separates the data 50/50. The worst pivot is the minimum or maximum value.</p>
<p>Consider in your code what happens if the list is already sorted &#8211; then your pivot selection (intlist[0]) will get the minimum value. Then your quicksort will recurse N times, and take N^2 comparisons to complete &#8211; JUST AS BAD AS BUBBLE SORT. So that&#8217;s a bad pivot selection.</p>
<p>How to improve pivot selection? If you take a whole pass over the data to pick an optimal pivot (the &#8220;bubble sort&#8221; suggestion), then you&#8217;ll waste as much time picking it as if you had picked the worst possible pivot!! So you can&#8217;t just write code to pick the best one.</p>
<p>Ideally, just pick an element from the list at random, or pick the middle element of the list (picking the middle element from the list gives you best performance on an already-sorted list).</p>
<p>As Fabse pointed out, it&#8217;s not really necessary to use arrays and manually keep track of their length, as Java has builtin list objects that do that for you. (They keep track of both the full length (called &#8220;capacity&#8221;) and the length of &#8220;good&#8221; items (called &#8220;size&#8221;)). However I would _not_ use a LinkedList. That won&#8217;t perform as you expect. I&#8217;d use a Vector, and be sure to set its initial capacity to the size of the source list.</p>
<p>Also why do you have 3 lists (less, greater, equal). Consider how many elements are put into the &#8220;equal&#8221; list. If you have 100 items, roughly distributed from 1 to 100, and a pivot of 50, then there&#8217;ll be about 50 items in the &#8220;less&#8221; list, 50 items in the &#8220;greater&#8221; list, and 1 item in the &#8220;equal&#8221; list. So don&#8217;t do that. Just have a &#8220;less than or equal to&#8221; list and a &#8220;greater than&#8221; list.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Hober Short</title>
		<link>http://hobershort.wordpress.com/2008/04/08/quicksort-in-java/#comment-335</link>
		<dc:creator>Hober Short</dc:creator>
		<pubDate>Wed, 09 Apr 2008 07:40:04 +0000</pubDate>
		<guid isPermaLink="false">http://hobershort.wordpress.com/?p=177#comment-335</guid>
		<description>The answer to your first question is: no. Java&#039;s so big I often forget about such things being implemented natively. I just use the basic arrays because I know &#039;em and they&#039;re simple.

Really, the most CPU and memory efficient implementation would probably indeed use a linked list. 

As to the bubble sort: it would be quicker and more efficient to just abort the search when you find an out of order item and begin with the quicksort. And as I understand Quicksort, there is no such thing as a &quot;best&quot; pivot. Everything gets sorted eventually. 

I also think it would be reasonable to assume that a sorting algorithm would be used on unsorted data. If there was any question, it&#039;s always possible for the program to test the data before passing it to the quicksort.</description>
		<content:encoded><![CDATA[<p>The answer to your first question is: no. Java&#8217;s so big I often forget about such things being implemented natively. I just use the basic arrays because I know &#8216;em and they&#8217;re simple.</p>
<p>Really, the most CPU and memory efficient implementation would probably indeed use a linked list. </p>
<p>As to the bubble sort: it would be quicker and more efficient to just abort the search when you find an out of order item and begin with the quicksort. And as I understand Quicksort, there is no such thing as a &#8220;best&#8221; pivot. Everything gets sorted eventually. </p>
<p>I also think it would be reasonable to assume that a sorting algorithm would be used on unsorted data. If there was any question, it&#8217;s always possible for the program to test the data before passing it to the quicksort.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
