4 ms·
I disagree. quicksort [] = [] quicksort (x:xs) = let smallerSorted = quicksort [a | a <- xs, a <= x] biggerSorted = quicksort [a | a
by tmountain 7y ago
I disagree.
quicksort [] = []
quicksort (x:xs) =
let smallerSorted = quicksort [a | a <- xs, a <= x]
biggerSorted = quicksort [a | a <- xs, a > x]
in smallerSorted ++ [x] ++ biggerSorted
- magicalhippo 7y agoNot that I know any Haskell, but wouldn't smallerSorted already include x due to <= operator? edit: also, how is the pivot element selected there?
- zests 7y agoBoth of your questions have the same answer. (x:xs) means x is the first element and xs is the rest.
- magicalhippo 7y agoAha! Thanks. Obviously picking first element as pivot makes for a very poor Quicksort. Though I presume a better approach, say median of first, mid and last elements, would add but an extra line?
- sullyj3 7y agoThe reason the first element is used as the pivot is that these are linked lists, not arrays, so it would take linear time to access the middle and end. This isn't a real quicksort.
- deleted 7y ago[deleted]
- edflsafoiewq 7y agoThat is (infamously) not quicksort.
- remcob 7y agoWhat's wrong with it?
- tossup8536 7y agoPerformance. Internal representation. You are not actually modifying things in place. Those are the equivalent of linked lists not arrays. That quicksort is not quick at all because the append operation in Haskell is linear. You can't use those lists to implement quicksort.
- lonelappde 7y agoHaskell is lazy. a ++ b === (head a) : ((tail a) ++ b) (plus the base case) It is only linear when you force it to evaluate, which ideally happens only once (amortized) in your program when the result is consumed. As long as you are careful, you don't get the bad quadratic performance that you'd get from something like eagerly appending a character to a string in a loop in Java. There are either gotchas, though, including relying on the compiler to do things in constant space that naively look linear, and also knowing when the compiler won't help you and you have to structure your computation manually.
- Koshkin 7y ago“Modifying things in place” is, from the logical standpoint, an unnatural and even dangerous thing. A person that is not familiar with (imperative) programming often has a hard time understanding variables and assignments (similar to some programmers not understanding pointers). Mathematics doesn’t have assignments, either. That should tell you something...
- recursive 7y agoIn that case, quicksort requires danger and artifice. In any case, it's not quicksort.
- vkou 7y agoIt mostly tells me that mathematics does not care about runtime or space performance. Which is fine, because mathematics is about solving abstract problems, not getting a Turing machine to solve concrete problems.
- CyberDildonics 7y agoWon't this have to iterate through linked lists and create multiple new heap allocations on each recursive step? Doesn't that imply n log n heap allocations just to sort a list?
- remcob 7y agoYes, but due to lazy-evaluation that won't happen until you do something with the sorted list. Your performance may just blow up in some seemingly unrelated place. My biggest problem with Haskell is how GC and lazy-evaluation makes it very difficult to reason about what the hardware is actually doing at a given point. I know there ways to inspect and control it, but I've found myself preferring languages that have simpler mental models.
- CyberDildonics 7y agoRight, by the time you have to control it, you are washing away all the advantages for using it.