Little Help implementing Quick-sort algorithm

Just getting started with Elixir and trying to implement Quick-sort algorithm using recursion. It seems like everything works but keying in this [8,16,3,7,23,77,9,30] broke the flow.
I was expecting [3, 7, 8, 9, 16, 23, 77, 30] but I did get this
[3, 7, 8, 16, 23, 77, 9, 30].
Also did a google search and saw other solutions calling filter or partition fro Enum module, I’m keen on using list comprehension implementing it.
Here is the code.

defmodule Quick do
  def sort([]), do: []
  def sort([head|tail]) do
   less_than_head = for x <- tail, x <= head, do: x
   greater_than_head = for x <- tail, x > head, do: x
    sort(less_than_head) ++ [head] ++ (greater_than_head)
   end
end

please do advice and how I can improve it.

You sort only less_than_head (BTW Your head is commonly called pivot) and greater_than_head is passed as is, so there is only partial sorting (only elements less than head are sorted).

EDIT: The big pro of using :lists.partition/2 is that it will split your list into two in one “walk” through the list instead of two, which can be improvement in case of long lists (but in such case the quick sort isn’t the best solution anyway, merge sort will work better).

So your 2 comprehensions can be easily replaced with:

{lesser, greater} = :lists.partition(& &1 <= head, tail)
4 Likes

Got deprecated warning with Enum.partition/2,
Enum.split_with/2 instead.
Works great!
Thanks

My mistake :lists.partition/2 still works
updated to this

defmodule Quick do
  import Enum, only: [split_with: 2]
  def sort([]), do: []
  def sort([head|tail]) do
    {pivot, greater_than_head} = split_with(tail, &(&1 <= head))
    sort(pivot) ++ [head] ++ (greater_than_head)
   end

end

big thanks @hauleth

1 Like

Thanks to you,
Will replace the list comprehension with Enum.partition

Not the lesser_than_head is usually called pivot, but the head is. Its the pivot point you use to compare.

Also you are still not sorting the greater_than_head :wink:

2 Likes

This should be written as:

def sort([]), do: []
def sort([pivot | tail]) do
  {lesser, greater} = Enum.split_by(tail, & &1 <= pivot)

  sort(lesser) ++ [pivot] ++ sort(greater)
end

As you still do not sort greater part as @NobbZ said.

Ohh,
It has been written well in the Idea, didn’t know I failed to include sort greater.
Thanks to you