In functional languages, you can combine sorting and unification (is this the real word?) In one go. Take the standard quick sort algorithm:
- Take the first element of the input (x) and the remaining elements (xs) - Make two new lists - left: all elements in xs smaller than or equal to x - right: all elements in xs larger than x - apply quick sort on the left and right lists - return the concatenation of the left list, x, and the right list - PS quick sort on an empty list is an empty list (don't forget base case!)
If you only need unique entries, replace
left: all elements in xs smaller than or equal to x
from
left: all elements in xs smaller than x
This is a one-pass O (n log n) algorithm.
An example implementation in F #:
let rec qsort = function | [] -> [] | x::xs -> let left,right = List.partition (fun el -> el <= x) xs qsort left @ [x] @ qsort right let rec qsortu = function | [] -> [] | x::xs -> let left = List.filter (fun el -> el < x) xs let right = List.filter (fun el -> el > x) xs qsortu left @ [x] @ qsortu right
And the test is interactive:
> qsortu [42;42;42;42;42];; val it : int list = [42] > qsortu [5;4;4;3;3;3;2;2;2;2;1];; val it : int list = [1; 2; 3; 4; 5] > qsortu [3;1;4;1;5;9;2;6;5;3;5;8;9];; val it : int list = [1; 2; 3; 4; 5; 6; 8; 9]
source share