F# Program to Implement Heap Sort

F# Program to Implement Heap Sort

Sorting plays a big role in programming because it helps organize data in a meaningful way. When data is sorted, tasks like searching, reporting, and analysis become much easier and faster. Heap Sort is one of the important sorting algorithms that programmers learn after understanding simpler sorts. It is known for being efficient and for not needing extra memory like some other advanced sorting methods.

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

Heap Sort is based on a special data structure called a heap, which is a type of binary tree. The idea is to first arrange the data into a heap and then repeatedly remove the largest value and place it at the end. Even though Heap Sort may feel a bit harder at first, it is very powerful and widely used in real systems. In this article, we will explore how to write an F# program to implement Heap Sort using different approaches, explained in a calm and beginner-friendly way.

Program 1: Heap Sort Using Arrays and Loops

This program shows the most common and traditional way to implement Heap Sort in F# using arrays and loops. It follows the standard textbook approach, which makes it a good starting point for beginners.

open System

let rec heapify (arr:int[]) n i =

    let mutable largest = i
    let left = 2 * i + 1
    let right = 2 * i + 2

    if left < n && arr.[left] > arr.[largest] then
        largest <- left

    if right < n && arr.[right] > arr.[largest] then
        largest <- right

    if largest <> i then

        let temp = arr.[i]
        arr.[i] <- arr.[largest]
        arr.[largest] <- temp

        heapify arr n largest


let heapSort (arr:int[]) =

    let n = arr.Length

    for i in (n / 2 - 1) .. -1 .. 0 do
        heapify arr n i


    for i in n - 1 .. -1 .. 1 do

        let temp = arr.[0]
        arr.[0] <- arr.[i]
        arr.[i] <- temp

        heapify arr i 0


[<EntryPoint>]
let main argv =

    let numbers = [| 12; 11; 13; 5; 6; 7 |]
    heapSort numbers

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

    0

This program works by first building a max heap and then repeatedly moving the largest value to the end of the array. It is useful because it shows exactly how Heap Sort works step by step. Beginners can understand how the heap structure controls the sorting process.

Program 2: Heap Sort with Clear Helper Functions

This program focuses on readability by keeping helper functions simple and well separated. It is helpful for beginners who want to understand each part clearly.

open System

let swap (arr:int[]) i j =

    let temp = arr.[i]
    arr.[i] <- arr.[j]
    arr.[j] <- temp


let rec heapify (arr:int[]) size index =

    let left = 2 * index + 1
    let right = 2 * index + 2
    let mutable largest = index

    if left < size && arr.[left] > arr.[largest] then
        largest <- left

    if right < size && arr.[right] > arr.[largest] then
        largest <- right

    if largest <> index then
        swap arr index largest
        heapify arr size largest


[<EntryPoint>]
let main argv =

    let arr = [| 4; 10; 3; 5; 1 |]
    let n = arr.Length

    for i in (n / 2 - 1) .. -1 .. 0 do
        heapify arr n i

    for i in n - 1 .. -1 .. 1 do
        swap arr 0 i
        heapify arr i 0

    printfn "Sorted array:"
    arr |> Array.iter (printf "%d ")

    0

This version makes the logic easier to follow by naming actions clearly. Beginners can focus on understanding heapify and swap without feeling overwhelmed. It is a good bridge between theory and real code.

Program 3: Heap Sort Using Recursion for Building the Heap

This program highlights the recursive nature of heapify while keeping the rest simple.

open System

let rec heapify (arr:int[]) n i =

    let largest =

        let left = 2 * i + 1
        let right = 2 * i + 2
        let mutable maxIndex = i

        if left < n && arr.[left] > arr.[maxIndex] then
            maxIndex <- left
        if right < n && arr.[right] > arr.[maxIndex] then
            maxIndex <- right

        maxIndex


    if largest <> i then

        let temp = arr.[i]
        arr.[i] <- arr.[largest]
        arr.[largest] <- temp

        heapify arr n largest


[<EntryPoint>]
let main argv =

    let numbers = [| 20; 1; 15; 3; 8 |]
    let n = numbers.Length

    for i in (n / 2 - 1) .. -1 .. 0 do
        heapify numbers n i

    for i in n - 1 .. -1 .. 1 do

        let temp = numbers.[0]
        numbers.[0] <- numbers.[i]
        numbers.[i] <- temp

        heapify numbers i 0


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

    0

This approach shows how recursion naturally fits the heap structure. Beginners can learn how a tree-like idea becomes simple recursive code. It also strengthens understanding of problem-solving using recursion.

Program 4: Heap Sort with Step-by-Step Logic

This program keeps everything explicit and slow-paced, which is ideal for beginners.

open System

let rec maxHeapify (arr:int[]) size root =

    let left = 2 * root + 1
    let right = 2 * root + 2
    let mutable largest = root

    if left < size && arr.[left] > arr.[largest] then
        largest <- left

    if right < size && arr.[right] > arr.[largest] then
        largest <- right

    if largest <> root then

        let temp = arr.[root]
        arr.[root] <- arr.[largest]
        arr.[largest] <- temp

        maxHeapify arr size largest


[<EntryPoint>]
let main argv =

    let data = [| 9; 4; 7; 1; 3; 6 |]
    let n = data.Length

    for i in (n / 2 - 1) .. -1 .. 0 do
        maxHeapify data n i

    for i in n - 1 .. -1 .. 1 do

        let temp = data.[0]
        data.[0] <- data.[i]
        data.[i] <- temp

        maxHeapify data i 0

    printfn "Sorted array:"
    data |> Array.iter (printf "%d ")

    0

This version is useful for beginners who like to trace code line by line. It clearly shows how the heap shrinks and how the largest value is placed correctly each time.

Program 5: Generic Heap Sort in F

This program shows how Heap Sort can work with any comparable type, not just integers.

open System

let inline heapSortGeneric (arr:'a[]) =

    let swap i j =

        let temp = arr.[i]
        arr.[i] <- arr.[j]
        arr.[j] <- temp


    let rec heapify n i =

        let left = 2 * i + 1
        let right = 2 * i + 2
        let mutable largest = i

        if left < n && arr.[left] > arr.[largest] then
            largest <- left
        if right < n && arr.[right] > arr.[largest] then
            largest <- right

        if largest <> i then
            swap i largest
            heapify n largest

    let n = arr.Length

    for i in (n / 2 - 1) .. -1 .. 0 do
        heapify n i

    for i in n - 1 .. -1 .. 1 do
        swap 0 i
        heapify i 0

    arr


[<EntryPoint>]
let main argv =

    let numbers = [| 14; 3; 2; 12; 6 |]
    let sorted = heapSortGeneric numbers

    printfn "Sorted array:"
    sorted |> Array.iter (printf "%d ")

    0

This program is powerful because it allows reuse of the same Heap Sort logic. Beginners can see how F# supports flexible and clean code while keeping performance strong.

Frequently Asked Questions (FAQ)

This section answers common beginner questions about Heap Sort in a simple and friendly way.

Q1. Why is Heap Sort considered efficient?
Heap Sort always runs in the same time for large data, which makes it reliable and efficient.

Q2. Is Heap Sort better than Quick Sort?
Heap Sort is more predictable, while Quick Sort is often faster in practice. Both are useful.

Q3. Is Heap Sort hard for beginners?
It may feel tricky at first, but once the heap idea is clear, the code becomes easier to understand.

Q4. Does Heap Sort need extra memory?
Heap Sort sorts data in place, so it does not need much extra memory.

Q5. Is Heap Sort used in real applications?
Yes, Heap Sort is used in systems where predictable performance is important.

Conclusion

Heap Sort is a powerful and reliable sorting algorithm that every programmer should learn. In this article, we explored several F# programs that implement Heap Sort using arrays, recursion, helper functions, and generic logic. Each version showed the same core idea in a beginner-friendly way.

The best way to learn Heap Sort is to practice writing the code and tracing how values move inside the heap. With patience and regular practice, Heap Sort will become clear and will strengthen your overall understanding of sorting and F# programming.

Scroll to Top