title: Pseudo-quicksort time complexity
body: <p>I know that quicksort has <code>O(n log n)</code> average time complexity. A pseudo-quicksort (which is only a quicksort when you look at it from far enough away, with a suitably high level of abstraction) that is often used to demonstrate the conciseness of functional languages is as follows (given in Haskell):</p>
  
  <pre><code>quicksort :: Ord a =&gt; [a] -&gt; [a]
  quicksort []     = []
  quicksort (p:xs) = quicksort [y | y&lt;-xs, y&lt;p] ++ [p] ++ quicksort [y | y&lt;-xs, y&gt;=p]
  </code></pre>
  
  <p>Okay, so I know this thing has problems. The biggest problem with this is that it does not sort in place, which is normally a big advantage of quicksort. Even if that didn't matter, it would still take longer than a typical quicksort because it has to do two passes of the list when it partitions it, and it does costly append operations to splice it back together afterwards. Further, the choice of the first element as the pivot is not the best choice.</p>
  
  <p>But <em>even considering all of that</em>, isn't the average <em>time</em> complexity of this quicksort the same as the standard quicksort? Namely, <code>O(n log n)</code>? Because the appends and the partition still have linear time complexity, even if they are inefficient.</p>