F# Program to Implement Bucket Sort

F# Program to Implement Bucket Sort

Bucket Sort is a simple and useful sorting algorithm that works best when the input values are spread evenly over a known range. Instead of comparing elements again and again like Bubble Sort or Insertion Sort, Bucket Sort places values into small groups called buckets. Each bucket is then sorted individually, and all buckets are combined to get the final sorted result. This idea makes Bucket Sort fast and easy to understand for beginners.

Pluralsight Logo
Accelerate your tech career
with hands-on learning.
Whether you're a tech newbie or a total pro,
get the skills and confidence to land your next move.
Start 10-Day Free Trial

In real life, Bucket Sort is often used when dealing with floating-point numbers, percentages, or scores that fall within a specific range. For example, sorting exam marks, temperature readings, or normalized data becomes easier with this approach. In F#, Bucket Sort is a great way to learn how arrays, lists, loops, and functions work together in a clean and readable way.

Program 1: Basic Bucket Sort Using Arrays

This program shows a simple Bucket Sort using arrays and loops. It works with decimal numbers between 0 and 1, which is the most common beginner example. The code is easy to follow and focuses on clarity.

open System

let bucketSort (arr: float[]) =

    let n = arr.Length
    let buckets = Array.init n (fun _ -> [])

    for i in 0 .. n - 1 do
        let index = int (arr.[i] * float n)
        buckets.[index] <- arr.[i] :: buckets.[index]

    let sortedBuckets = buckets |> Array.map List.sort
    let mutable k = 0

    for i in 0 .. n - 1 do

        for value in sortedBuckets.[i] do

            arr.[k] <- value
            k <- k + 1


[<EntryPoint>]
let main argv =

    let numbers = [| 0.42; 0.32; 0.23; 0.52; 0.25; 0.47; 0.51 |]

    bucketSort numbers
    numbers |> Array.iter (printf "%.2f ")

    0

This program creates empty buckets first and then places each number into the correct bucket based on its value. Each bucket is sorted using a built-in sort, which keeps things simple. Beginners can learn how data moves step by step from the original array into buckets and back again.

Program 2: Bucket Sort Using Lists Instead of Arrays

This version uses lists more heavily, which fits well with the functional style of F#. It still performs Bucket Sort but focuses on immutability and clean data flow.

open System

let bucketSortList numbers =

    let n = List.length numbers
    let buckets = Array.init n (fun _ -> [])

    numbers
    |> List.iter (fun x ->
        let index = int (x * float n)
        buckets.[index] <- x :: buckets.[index])

    buckets
    |> Array.collect (fun b -> b |> List.sort |> List.toArray)
    |> Array.toList


[<EntryPoint>]
let main argv =

    let numbers = [0.78; 0.17; 0.39; 0.26; 0.72; 0.94]
    let sorted = bucketSortList numbers
    sorted |> List.iter (printf "%.2f ")

    0

Here, the data flows smoothly from input list to buckets and back to a sorted list. This approach helps beginners understand functional thinking in F#. It is especially useful when working with immutable data structures.

Program 3: Bucket Sort Using Integer Range

This program adapts Bucket Sort for integers within a known range. It is useful when working with marks, scores, or small numeric ranges.

open System

let bucketSortIntegers (arr:int[]) maxValue =

    let buckets = Array.init (maxValue + 1) (fun _ -> 0)

    for value in arr do
        buckets.[value] <- buckets.[value] + 1

    let mutable index = 0

    for i in 0 .. maxValue do

        for _ in 1 .. buckets.[i] do

            arr.[index] <- i
            index <- index + 1


[<EntryPoint>]
let main argv =

    let numbers = [| 4; 2; 2; 8; 3; 3; 1 |]
    bucketSortIntegers numbers 8
    numbers |> Array.iter (printf "%d ")

    0

This version behaves like a counting-based Bucket Sort. It is very fast and easy to understand. Beginners can clearly see how values are counted and placed back in order.

Program 4: Recursive Bucket Sort for Learning Purposes

This program uses recursion to process buckets. While not the most efficient, it is great for learning recursion in F#.

open System

let rec flatten buckets =

    match buckets with
    | [] -> []
    | head :: tail -> List.sort head @ flatten tail


let bucketSortRecursive numbers =

    let n = List.length numbers
    let buckets = Array.init n (fun _ -> [])

    numbers
    |> List.iter (fun x ->
        let index = int (x * float n)
        buckets.[index] <- x :: buckets.[index])

    flatten (Array.toList buckets)


[<EntryPoint>]
let main argv =

    let numbers = [0.66; 0.12; 0.89; 0.45; 0.33]
    let sorted = bucketSortRecursive numbers
    sorted |> List.iter (printf "%.2f ")

    0

This approach helps beginners understand how recursion can replace loops. It also shows how sorting can be broken into smaller problems and combined later.

Program 5: Bucket Sort with Custom Bucket Size

This program allows control over bucket size, making it more flexible for different datasets.

open System

let bucketSortCustom (arr: float[]) bucketCount =

    let buckets = Array.init bucketCount (fun _ -> [])

    for value in arr do

        let index = int (value * float bucketCount)
        let safeIndex = if index >= bucketCount then bucketCount - 1 else index
        buckets.[safeIndex] <- value :: buckets.[safeIndex]

    let mutable i = 0

    for bucket in buckets do

        let sortedBucket = bucket |> List.sort

        for value in sortedBucket do
            arr.[i] <- value
            i <- i + 1


[<EntryPoint>]
let main argv =

    let numbers = [| 0.21; 0.44; 0.68; 0.12; 0.89; 0.55 |]
    bucketSortCustom numbers 5
    numbers |> Array.iter (printf "%.2f ")

    0

This version shows how Bucket Sort can be adjusted for different needs. Beginners learn how flexibility in design can improve real-world programs.

Program 6: Bucket Sort for Negative Numbers Only

This program shows how Bucket Sort can be applied when the array contains only negative numbers. Since Bucket Sort usually works with positive ranges, the idea here is to first convert negative values into positive ones, sort them using buckets, and then convert them back to negative values at the end. This keeps the logic simple and easy for beginners to understand.

open System

let bucketSortNegative (arr:int[]) =

    let n = arr.Length
    let positives = arr |> Array.map abs
    let maxVal = Array.max positives

    let bucketCount = maxVal + 1
    let buckets = Array.init bucketCount (fun _ -> 0)

    for value in positives do
        buckets.[value] <- buckets.[value] + 1

    let mutable index = 0

    for i in bucketCount - 1 .. -1 .. 0 do

        for _ in 1 .. buckets.[i] do

            arr.[index] <- -i
            index <- index + 1


[<EntryPoint>]
let main argv =

    let numbers = [| -5; -1; -3; -8; -2; -5 |]
    bucketSortNegative numbers

    printfn "Sorted negative numbers:"
    numbers |> Array.iter (printf "%d ")

    0

This program works by first converting all negative numbers into their positive form using the absolute value. These values are then placed into buckets based on their size, similar to a counting-style Bucket Sort. After sorting, the program rebuilds the original array in reverse order and restores the negative sign. This is useful for beginners because it avoids complex bucket range math while clearly showing how Bucket Sort can be adapted for special cases like negative-only data.

Frequently Asked Questions (FAQ)

This section answers common beginner questions about Bucket Sort in F# using simple explanations.

Q1. What type of data is Bucket Sort best for?
Bucket Sort works best when the data is evenly distributed over a known range, such as percentages or decimal values between 0 and 1.

Q2. Is Bucket Sort faster than Bubble Sort?
Yes, in many cases Bucket Sort is much faster because it avoids repeated comparisons and works in groups.

Q3. Can Bucket Sort handle negative numbers?
Bucket Sort can handle negative numbers, but the logic needs adjustment to map values correctly into buckets.

Q4. Is Bucket Sort stable in F#?
Bucket Sort can be stable if the sorting method inside each bucket is stable, such as List.sort.

Q5. Should beginners learn Bucket Sort?
Yes, Bucket Sort helps beginners understand data grouping and is a good step toward learning advanced sorting techniques.

Conclusion

Bucket Sort is a friendly and powerful sorting algorithm that fits well with F# programming. It teaches important ideas like grouping data, working with arrays and lists, and combining results in a clean way. Through multiple programs, you can see how the same idea can be written using loops, recursion, and functional styles.

By practicing these F# Bucket Sort programs, beginners can build confidence and improve problem-solving skills. Try changing the input data, bucket sizes, or even mixing sorting methods to explore more. With time and practice, sorting algorithms like Bucket Sort will feel natural and fun to use.

Scroll to Top