Haskell sort - odd and even sort
Haskell is a purely functional static and non-strict language, i.e., it does not evaluate expressions until needed. With its high degree of pattern matching, this combination allows greater control over complex problems and allows high-order functions to be a viable solution. However, Haskell is not a beginner-friendly language and has a steep learning curve. Moreover, its pure functionality requires extra effort while creating functions and working with the language.
Logic
The odd and even sort, also known as the brick sort, is a variation of the bubble sort algorithm. The odd-even sort is a simple algorithm that works by repetitively comparing and swapping (if need be) adjacent elements in a list until the entire list is sorted. The algorithm can be split into two parts: the odd pass and the even pass.
In the odd pass, elements at odd indices (i.e., 1, 3, 5, ... ) are compared with their immediate next odd element, i.e., the element at index 1 will compare itself to the element at index 3. If the current element, i.e., the element at index 1, is larger, it is swapped with the element at index 3. In this way, odd-indexed elements are swapped through a bubble sort variant. This same process is implemented for the even pass with even indices (i.e., 0, 2, 4, ...).
After the first traversal through both passes, the algorithm continues alternating between both passes until the entire list is sorted.
Code
Let us now look at the code implementation of the odd-even sort in Haskell.
-- Swap elements at the given indices in a listswap :: Int -> Int -> [a] -> [a]swap i j xs = [if k == i then xs !! jelse if k == j then xs !! ielse xs !! k | k <- [0..length xs - 1]]-- Perform a single pass of the odd-even sort algorithmoddEvenPass :: (Ord a) => [a] -> [a]oddEvenPass [] = []oddEvenPass [x] = [x]oddEvenPass (x1:x2:xs)| x1 > x2 = swap 0 1 (x1:x2:xs)| otherwise = x1 : oddEvenPass (x2:xs)-- Perform the odd-even sort algorithm until no swaps are neededoddEvenSort :: (Ord a) => [a] -> [a]oddEvenSort xs| sorted = xs| otherwise = oddEvenSort sortedListwheresortedList = oddEvenPass xssorted = sortedList == xs-- Execute example codemain :: IO ()main = dolet unsortedList = [5, 2, 9, 1, 2, 6, 4]putStrLn "Unsorted list:"print unsortedListlet sortedList = oddEvenSort unsortedListputStrLn "Sorted list:"print sortedList
We will now break down the code.
Lines 1–3: The
swapfunction swaps two elements at indicesiandjin the list. It does so by directly creating a new list by iterating through the indices of the input list and swapping the elements needed.Lines 7–13: The
oddEvenPassfunction ensures that it swaps elements at adjacent odd indices in each pass while keeping elements at adjacent even indices. This moves the larger elements to the end of the list (in ascending order).Lines 16–22: The
oddEvenSortfunction calls theoddEvenPassfunction repeatedly until the list is fully sorted and does not have more swaps.Lines 23–33: The
mainfunction is the driver code for the program. It runs the functions created above and prints out its result.
Complexities
The time complexity of this algorithm is
This algorithm's space complexity is
Conclusion
Overall, this algorithm is a simplistic one due to its understandability. However, its poor time complexity makes it inefficient for larger datasets. This is why it is generally not used in sorting tasks and is only studied for educational purposes.
Note: To learn more sorting algorithms in Haskell, select any from the list below.
Free Resources