<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
More Wikipedia<br><br><span class="Apple-style-span" style="font-family: sans-serif; line-height: 19px; "><p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; ">Due to its simplicity, bubble sort is often used to introduce the concept of an algorithm, or a sorting algorithm, to introductory&nbsp;<a href="http://en.wikipedia.org/wiki/Computer_science" title="Computer science" style="text-decoration: none; color: rgb(0, 43, 184); background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: initial initial; background-repeat: initial initial; ">computer science</a>&nbsp;students. However, some researchers such as Owen Astrachan have gone to great lengths to disparage bubble sort and its continued popularity in computer science education, recommending that it no longer even be taught.<sup id="cite_ref-Astrachan2003_0-0" class="reference" style="line-height: 1em; font-weight: normal; font-style: normal; "><a href="http://en.wikipedia.org/wiki/Bubble_sort#cite_note-Astrachan2003-0" style="text-decoration: none; color: rgb(0, 43, 184); background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; white-space: nowrap; background-position: initial initial; background-repeat: initial initial; "><span>[</span>1<span>]</span></a></sup></p><p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; ">The&nbsp;<a href="http://en.wikipedia.org/wiki/Jargon_file" title="Jargon file" class="mw-redirect" style="text-decoration: none; color: rgb(0, 43, 184); background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: initial initial; background-repeat: initial initial; ">Jargon file</a>, which famously calls&nbsp;<a href="http://en.wikipedia.org/wiki/Bogosort" title="Bogosort" style="text-decoration: none; color: rgb(0, 43, 184); background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: initial initial; background-repeat: initial initial; ">bogosort</a>&nbsp;"the archetypical perversely awful algorithm", also calls bubble sort "the generic&nbsp;<b>bad</b>&nbsp;algorithm".<sup id="cite_ref-1" class="reference" style="line-height: 1em; font-weight: normal; font-style: normal; "><a href="http://en.wikipedia.org/wiki/Bubble_sort#cite_note-1" style="text-decoration: none; color: rgb(0, 43, 184); background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; white-space: nowrap; background-position: initial initial; background-repeat: initial initial; "><span>[</span>2<span>]</span></a></sup>&nbsp;<a href="http://en.wikipedia.org/wiki/Donald_Knuth" title="Donald Knuth" style="text-decoration: none; color: rgb(0, 43, 184); background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: initial initial; background-repeat: initial initial; ">Donald Knuth</a>, in his famous book&nbsp;<i><a href="http://en.wikipedia.org/wiki/The_Art_of_Computer_Programming" title="The Art of Computer Programming" style="text-decoration: none; color: rgb(0, 43, 184); background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: initial initial; background-repeat: initial initial; ">The Art of Computer Programming</a></i>, concluded that "the bubble sort seems to have nothing to recommend it, except a catchy name and the fact that it leads to some interesting theoretical problems", some of which he then discusses.</p></span><div><br></div><div>...and in case my previous post failed &nbsp;(not used to posting from email)</div><div><br></div><div><span class="Apple-style-span" style="font-family: sans-serif; line-height: 19px; ">However, one significant advantage that bubble sort has over most other implementations, even&nbsp;<a href="http://en.wikipedia.org/wiki/QuickSort" title="QuickSort" class="mw-redirect" style="text-decoration: none; color: rgb(0, 43, 184); background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: initial initial; background-repeat: initial initial; ">QuickSort</a>, is that the ability to detect that the list is sorted is efficiently built into the algorithm. Performance of bubble sort over an already-sorted list (best-case) is&nbsp;<i>O</i>(<i>n</i>). By contrast, most other algorithms, even those with better average-case complexity, perform their entire sorting process on the set and thus are more complex. However,&nbsp;<a href="http://en.wikipedia.org/wiki/Insertion_sort" title="Insertion sort" style="text-decoration: underline; color: rgb(0, 43, 184); background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: initial initial; background-repeat: initial initial; ">Insertion sort</a>&nbsp;also has this mechanism, and also performs better on a list that is substantially sorted (having a small number of<a href="http://en.wikipedia.org/wiki/Inversion_(computer_science)" title="Inversion (computer science)" style="text-decoration: none; color: rgb(0, 43, 184); background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: initial initial; background-repeat: initial initial; ">inversions</a>).</span></div><div><br></div><div><br></div><div><br>&gt; Date: Mon, 8 Mar 2010 09:53:44 -0600<br>&gt; Subject: Re: [plt-scheme] Do no evil<br>&gt; From: robby@eecs.northwestern.edu<br>&gt; To: matthias@ccs.neu.edu<br>&gt; CC: wookiz@hotmail.com; plt-scheme@list.cs.brown.edu<br>&gt; <br>&gt; I tried to find that quote, but didn't find anything better than what<br>&gt; it says in the "in practice" section of Wikipedia.<br>&gt; <br>&gt; (And, of course, we are in a loop here, but this is a new piece of<br>&gt; information related to the loop-- I don't mean for us to cover any old<br>&gt; ground again. Apologies in advance if we head off thataway.)<br>&gt; <br>&gt; Robby<br>&gt; <br>&gt; On Mon, Mar 8, 2010 at 9:47 AM, Matthias Felleisen &lt;matthias@ccs.neu.edu&gt; wrote:<br>&gt; &gt;<br>&gt; &gt; Knuth wrote this up in the 1960s. Anyone who teaches bubble sort<br>&gt; &gt; in the 20xy is teaching 1970s computer science. But I think I am<br>&gt; &gt; now in some kind of loop with wooks.<br>&gt; &gt;<br>&gt; &gt;<br>&gt; &gt;<br>&gt; &gt;<br>&gt; &gt; On Mar 8, 2010, at 10:44 AM, Robby Findler wrote:<br>&gt; &gt;<br>&gt; &gt;&gt; Continuing my contrarianocity: When I was taught the bubble sort, I<br>&gt; &gt;&gt; wish that my teacher had taken the time to explain bubble sort's place<br>&gt; &gt;&gt; in the pantheon of sorting algorithms (there is essentially no metric<br>&gt; &gt;&gt; under which it better than some other sort, with the possible<br>&gt; &gt;&gt; exception of ease of implementation in Fortran 70).<br>&gt; &gt;&gt;<br>&gt; &gt;&gt; Robby<br>&gt; &gt;&gt;<br>&gt; &gt;&gt; On Mon, Mar 8, 2010 at 9:39 AM, Matthias Felleisen &lt;matthias@ccs.neu.edu&gt;<br>&gt; &gt;&gt; wrote:<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; I have taken Veer's understanding to derive a relatively short<br>&gt; &gt;&gt;&gt; form of bubble sort in the plain Scheme language:<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; (define (bsort v)<br>&gt; &gt;&gt;&gt; &nbsp;(define (sweep v i clean?)<br>&gt; &gt;&gt;&gt; &nbsp; (cond<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; [(= i (- n 1)) (if clean? v (sweep v 0 true))]<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; [else (if (&lt;= (vector-ref v i) (vector-ref v (+ i 1)))<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (sweep v (+ i 1) clean?)<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (sweep (swap v i) (+ i 1) false))]))<br>&gt; &gt;&gt;&gt; &nbsp;(define n (vector-length v))<br>&gt; &gt;&gt;&gt; &nbsp;;; IN<br>&gt; &gt;&gt;&gt; &nbsp;(sweep v 0 true))<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; ;; swap: factored out as suggested by Noel,<br>&gt; &gt;&gt;&gt; ;; do it with build-vector and weep! bubble<br>&gt; &gt;&gt;&gt; ;; demos how bad FP's performance can be :-)<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; But I have done so in ASL just to demonstrate that it is feasible.<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; You start with the generative recursion idea of bubbling through<br>&gt; &gt;&gt;&gt; the array until there are no more out of place items left. Then<br>&gt; &gt;&gt;&gt; you're done. Then you 'edit' the program with two observation.<br>&gt; &gt;&gt;&gt; If you were in #lang scheme, you'd come up with the above<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; The derivation is appended below. -- Matthias<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; ;; [Vec Number] -&gt; [Vec Number]<br>&gt; &gt;&gt;&gt; ;; create a sorted version of v<br>&gt; &gt;&gt;&gt; ;; effect: modify v<br>&gt; &gt;&gt;&gt; (define (bsort.v0 v)<br>&gt; &gt;&gt;&gt; &nbsp;(local (;; Result = (list [Vec Number] Boolean)<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; ;; [Vec Number] -&gt; [Vec Number]<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; ;; (effect) create a sorted version of v<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; ;; generative recursion: swap-all until nothing to swap anymore<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; ;; termination: there are only a finite number of swaps<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; (define (generative-driver v)<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (local ((define v+flag (sweep v))<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (define newv &nbsp; (first v+flag))<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (define clean? (second v+flag)))<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (if clean? v (generative-driver v))))<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; ;; [Vec Number] -&gt; Result<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; ;; (effect) swap all out of place neighbors throughout vector<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; (define (sweep v)<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (local (;; [Vec Number] N Boolean -&gt; Result<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;; accumulators: [0,i) is bubbled -- clean? no swaps so<br>&gt; &gt;&gt;&gt; far<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (define (sweep v i clean?)<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (cond<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [(= i (- (vector-length v) 1)) (list v clean?)]<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [else (if (&lt;= (vector-ref v i) (vector-ref v (+ i<br>&gt; &gt;&gt;&gt; 1)))<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (sweep v (+ i 1) clean?)<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (sweep (swap v i) (+ i 1) false))])))<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (sweep v 0 true))))<br>&gt; &gt;&gt;&gt; &nbsp; ;; IN<br>&gt; &gt;&gt;&gt; &nbsp; (generative-driver v)))<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; ;; fold the geneative-driver into the sweep function<br>&gt; &gt;&gt;&gt; ;; observation: the base case packages up the result,<br>&gt; &gt;&gt;&gt; ;; which is immediately unfolded and used for another call<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; (define (bsort.v1 v)<br>&gt; &gt;&gt;&gt; &nbsp;(local (;; [Vec Number] -&gt; [Vec Number]<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; ;; (effect) swap all out of place neighbors throughout vector<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; (define (sweep v)<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (local (;; [Vec Number] N Boolean -&gt; Result<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;; accumulators: [0,i) is bubbled -- clean? no swaps so<br>&gt; &gt;&gt;&gt; far<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (define (sweep v i clean?)<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (cond<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [(= i (- (vector-length v) 1))<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(if clean? v (sweep v 0 true))]<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [else (if (&lt;= (vector-ref v i) (vector-ref v (+ i<br>&gt; &gt;&gt;&gt; 1)))<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (sweep v (+ i 1) clean?)<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (sweep (swap v i) (+ i 1) false))])))<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (sweep v 0 true))))<br>&gt; &gt;&gt;&gt; &nbsp; ;; IN<br>&gt; &gt;&gt;&gt; &nbsp; (sweep v)))<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; ;; eliminate the indirection from 1-ary sweep through 1-ary sweep<br>&gt; &gt;&gt;&gt; ;; lift the vector-length computation<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; (define (bsort v)<br>&gt; &gt;&gt;&gt; &nbsp;(local (;; [Vec Number] N Boolean -&gt; Result<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; ;; accumulators: [0,i) is bubbled -- clean? no swaps so far<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; (define (sweep v i clean?)<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (cond<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [(= i (- n 1)) (if clean? v (sweep v 0 true))]<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [else (if (&lt;= (vector-ref v i) (vector-ref v (+ i 1)))<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (sweep v (+ i 1) clean?)<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (sweep (swap v i) (+ i 1) false))]))<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; ;; where<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; (define n (vector-length v)))<br>&gt; &gt;&gt;&gt; &nbsp; ;; IN<br>&gt; &gt;&gt;&gt; &nbsp; (sweep v 0 true)))<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; ;;<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; -----------------------------------------------------------------------------<br>&gt; &gt;&gt;&gt; ;; auxiliaries<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; ;; [Vec Number] N -&gt; [Vec Number]<br>&gt; &gt;&gt;&gt; ;; swap items i and i+1 in v<br>&gt; &gt;&gt;&gt; (define (swap v i)<br>&gt; &gt;&gt;&gt; &nbsp;(local ((define v@i (vector-ref v i)))<br>&gt; &gt;&gt;&gt; &nbsp; (begin<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; (vector-set! v i (vector-ref v (+ i 1)))<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; (vector-set! v (+ i 1) v@i)<br>&gt; &gt;&gt;&gt; &nbsp; &nbsp; v)))<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; ;;<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; -----------------------------------------------------------------------------<br>&gt; &gt;&gt;&gt; ;; tests<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; (define (generate-test) (vector 3 1 9 8 5 6 7 0 4 2))<br>&gt; &gt;&gt;&gt; (define swapped0 (vector 1 3 9 8 5 6 7 0 4 2))<br>&gt; &gt;&gt;&gt; (define swapped2 (vector 3 1 8 9 5 6 7 0 4 2))<br>&gt; &gt;&gt;&gt; (define sorted (vector 0 1 2 3 4 5 6 7 8 9))<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; (check-expect (swap (generate-test) 0) swapped0)<br>&gt; &gt;&gt;&gt; (check-expect (swap (generate-test) 2) swapped2)<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; (check-expect (bsort (generate-test)) sorted)<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;&gt;&gt; _________________________________________________<br>&gt; &gt;&gt;&gt; &nbsp;For list-related administrative tasks:<br>&gt; &gt;&gt;&gt; &nbsp;http://list.cs.brown.edu/mailman/listinfo/plt-scheme<br>&gt; &gt;&gt;&gt;<br>&gt; &gt;<br>&gt; &gt;<br></div>                                               <br /><hr />Got a cool Hotmail story? <a href='http://clk.atdmt.com/UKM/go/195013117/direct/01/' target='_new'>Tell us now</a></body>
</html>