{"id":520,"date":"2011-11-09T20:20:54","date_gmt":"2011-11-09T20:20:54","guid":{"rendered":"http:\/\/psyphi.net\/blog\/?p=520"},"modified":"2011-11-09T20:20:54","modified_gmt":"2011-11-09T20:20:54","slug":"3-sorts-of-sort","status":"publish","type":"post","link":"https:\/\/psyphi.net\/blog\/2011\/11\/3-sorts-of-sort\/","title":{"rendered":"3 sorts of sort"},"content":{"rendered":"<p>I&#8217;ve been fiddling around recently with some stuff which I&#8217;m sure I covered in my CS degree 16 (Gah! Really?) years ago but have had to re-educate myself about. Namely a few different implementations of sort. I implemented three types in Perl with some reacquaintance of the mechanisms via Wikipedia. I found a few existing examples of sort algorithms in Perl but they generally looked a bit unpleasant so like all programmers I decided to write my own (complete with errors, as an exercise to the reader). Here I&#8217;ve also added some notes, mostly to myself, which are largely unsubstantiated because I haven&#8217;t measured memory, speed or recursion depth, for example (though these are well-documented elsewhere).<\/p>\n<p>1. Bubble Sort<\/p>\n<pre><code>#!\/usr\/bin\/perl -w\r\nuse strict;\r\nuse warnings;\r\n\r\nmy $set    = [map { int rand() * 99 } (0..40)];\r\nprint \"in:  @{$set}\\n\";\r\n\r\nmy $sorted = bubblesort($set);\r\nprint \"out: @{$sorted}\\n\";\r\n\r\nsub bubblesort {\r\n  my ($in)     = @_;\r\n  my $out      = [@{$in}];\r\n  my $length   = scalar @{$in};\r\n  my $modified = 1;\r\n\r\n  while($modified) {\r\n    $modified = 0;\r\n    for my $i (0..$length-2) {\r\n      if($out-&gt;[$i] &gt; $out-&gt;[$i+1]) {\r\n\t($out-&gt;[$i], $out-&gt;[$i+1]) = ($out-&gt;[$i+1], $out-&gt;[$i]);\r\n\t$modified = 1;\r\n      }\r\n    }\r\n  }\r\n\r\n  return $out;\r\n}<\/code><\/pre>\n<p>\n Bubblesort iterates through each element of the list up to the last but one, comparing to the next element in the list. If it&#8217;s greater the values are swapped. The process repeats until no modifications are made to the list.\n<\/p>\n<p>\n Pros: doesn&#8217;t use much memory &#8211; values are swapped in situ; doesn&#8217;t perform deep recursion; is easy to read\n<\/p>\n<p>\n Cons: It&#8217;s pretty slow. The worst-case complexity is <i>O(n<sup>2<\/sup>)<\/i> passes (for each value in the list each value in the list is processed once).\n<\/p>\n<p>2. Merge Sort<\/p>\n<pre><code>#!\/usr\/bin\/perl\r\nuse strict;\r\nuse warnings;\r\n\r\nmy $set    = [map { int rand() * 99 } (0..40)];\r\nprint \"in:  @{$set}\\n\";\r\n\r\nmy $sorted = mergesort($set);\r\nprint \"out: @{$sorted}\\n\";\r\n\r\nsub mergesort {\r\n  my ($in) = @_;\r\n\r\n  my $length = scalar @{$in};\r\n  if($length &lt; = 1) {\r\n    return $in;\r\n  }\r\n\r\n  my $partition = $length \/ 2;\r\n  my $left      = [@{$in}[0..$partition-1]];\r\n  my $right     = [@{$in}[$partition..$length-1]];\r\n\r\n  return merge(mergesort($left), mergesort($right));\r\n}\r\n\r\nsub merge {\r\n  my ($left, $right) = @_;\r\n  my $merge = [];\r\n\r\n  while(scalar @{$left} || scalar @{$right}) {\r\n    if(scalar @{$left} &amp;&amp; scalar @{$right}) {\r\n      if($left-&gt;[0] &lt; $right-&gt;[0]) {\r\n\tpush @{$merge}, shift @{$left};\r\n      } else {\r\n\tpush @{$merge}, shift @{$right};\r\n      }\r\n    } elsif(scalar @{$left}) {\r\n      push @{$merge}, shift @{$left};\r\n    } elsif(scalar @{$right}) {\r\n      push @{$merge}, shift @{$right};\r\n    }\r\n  }\r\n  return $merge;\r\n}<\/code><\/pre>\n<p>\n Mergesort recurses through the list, in each iteration breaking the remaining list in half. Once broken down to individual elements, each pair of elements\/lists at each depth of recursion is reconstituted into a new ordered list and returned.\n<\/p>\n<p>\n Pros: generally quicker than bubblesort; <i>O(n log n)<\/i> complexity.\n<\/p>\n<p>\n Cons: quite difficult to read\n<\/p>\n<p>3. Quicksort<\/p>\n<pre><code>#!\/usr\/bin\/perl\r\nuse strict;\r\nuse warnings;\r\n\r\nmy $set    = [map { int rand() * 99 } (0..40)];\r\nprint \"in:  @{$set}\\n\";\r\n\r\nmy $sorted = quicksort($set);\r\nprint \"out: @{$sorted}\\n\";\r\n\r\nsub quicksort {\r\n  my ($in) = @_;\r\n\r\n  my $length = scalar @{$in};\r\n  if($length &lt; = 1) {\r\n    return $in;\r\n  }\r\n\r\n  my $pivot = splice @{$in}, $length \/ 2, 1;\r\n  my $left  = [];\r\n  my $right = [];\r\n\r\n  for my $v (@{$in}) {\r\n    if($v &lt; $pivot) {\r\n      push @{$left}, $v;\r\n    } else {\r\n      push @{$right}, $v;\r\n    }\r\n  }\r\n\r\n  return [@{quicksort($left)}, $pivot, @{quicksort($right)}];\r\n}<\/code><\/code><\/pre>\n<p>\n Quicksort is probably the best known of all the sort algorithms out there. It&#8217;s easier to read than Mergesort, though arguably still not as easy as Bubblesort, but it&#8217;s a common pattern and its speed makes up for anything lacking in readability. At each iteration a pivot is selected and removed from the list. The remaining list is scanned and for element lower than the pivot is put in a new &#8220;left&#8221; list and each greater element is put into a new &#8220;right&#8221; list. The returned result is a merged recursive quicksort of the left list, the pivot and the right list.\n<\/p>\n<p>\n In this example I&#8217;m picking the middle element of the list as the pivot. I&#8217;m sure there are entire branches of discrete mathematics dealing with how to choose the pivot based on the type of input data.\n<\/p>\n<p>\n Pros: (One of?) the fastest sort algorithm(s) around; Reasonably efficient memory usage and recursion depth. Average <i>O(n log n)<\/i> complexity again (worst is <i>O(n<sup>2<\/sup>)<\/i>).\n<\/p>\n<p>\n Perhaps it&#8217;s worth noting that in 25-odd years of programming computers I&#8217;ve only ever had to examine the inner workings of sort routines as part of my degree &#8211; never before, nor after, but it&#8217;s certainly brought back a few memories.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been fiddling around recently with some stuff which I&#8217;m sure I covered in my CS degree 16 (Gah! Really?) years ago but have had to re-educate myself about. Namely a few different implementations of sort. I implemented three types in Perl with some reacquaintance of the mechanisms via Wikipedia. I found a few existing &hellip; <a href=\"https:\/\/psyphi.net\/blog\/2011\/11\/3-sorts-of-sort\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;3 sorts of sort&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[11],"tags":[13,21,1081],"class_list":["post-520","post","type-post","status-publish","format-standard","hentry","category-programming","tag-code","tag-perl","tag-programming"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/psyphi.net\/blog\/wp-json\/wp\/v2\/posts\/520","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/psyphi.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/psyphi.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/psyphi.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/psyphi.net\/blog\/wp-json\/wp\/v2\/comments?post=520"}],"version-history":[{"count":7,"href":"https:\/\/psyphi.net\/blog\/wp-json\/wp\/v2\/posts\/520\/revisions"}],"predecessor-version":[{"id":528,"href":"https:\/\/psyphi.net\/blog\/wp-json\/wp\/v2\/posts\/520\/revisions\/528"}],"wp:attachment":[{"href":"https:\/\/psyphi.net\/blog\/wp-json\/wp\/v2\/media?parent=520"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/psyphi.net\/blog\/wp-json\/wp\/v2\/categories?post=520"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/psyphi.net\/blog\/wp-json\/wp\/v2\/tags?post=520"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}