Heap Sorter Algorithm

Heap Sort Algorithm is a comparison-based sorting technique that utilizes the binary heap data structure to sort a sequence of elements in either ascending or descending order. The main idea behind the algorithm is to build a binary heap (either max-heap or min-heap) from the given input data, then repeatedly extract the root element and insert it into the sorted section of the array while maintaining the heap property. In the first step, the algorithm builds a max-heap for sorting in ascending order (or a min-heap for sorting in descending order) using the input data. This process involves iteratively comparing parent and child nodes and swapping them if they do not follow the heap property. Once the heap is constructed, the algorithm then repeatedly extracts the root element (the largest or smallest element in the heap) and swaps it with the last element of the unsorted part of the array until the entire array is sorted. After each extraction, the heap is restructured to maintain its properties. This process continues until the entire array is sorted, resulting in an efficient and in-place sorting algorithm with a time complexity of O(n log n) for both the best and worst cases.
using System.Collections.Generic;

namespace Algorithms.Sorters.Comparison
{
    /// <summary>
    /// Heap sort is a comparison based sorting technique
    /// based on Binary Heap data structure.
    /// </summary>
    /// <typeparam name="T">Input array type.</typeparam>
    public class HeapSorter<T> : IComparisonSorter<T>
    {
        /// <summary>
        /// Sorts input array using heap sort algorithm.
        /// </summary>
        /// <param name="array">Input array.</param>
        /// <param name="comparer">Comparer type for elements.</param>
        public void Sort(T[] array, IComparer<T> comparer) => HeapSort(array, comparer);

        private static void HeapSort(IList<T> data, IComparer<T> comparer)
        {
            var heapSize = data.Count;
            for (var p = (heapSize - 1) / 2; p >= 0; p--)
            {
                MakeHeap(data, heapSize, p, comparer);
            }

            for (var i = data.Count - 1; i > 0; i--)
            {
                var temp = data[i];
                data[i] = data[0];
                data[0] = temp;

                heapSize--;
                MakeHeap(data, heapSize, 0, comparer);
            }
        }

        private static void MakeHeap(IList<T> input, int heapSize, int index, IComparer<T> comparer)
        {
            var rIndex = index;

            while (true)
            {
                var left = (rIndex + 1) * 2 - 1;
                var right = (rIndex + 1) * 2;
                var largest = left < heapSize && comparer.Compare(input[left], input[rIndex]) == 1 ? left : rIndex;

                // finds the index of the largest
                if (right < heapSize && comparer.Compare(input[right], input[largest]) == 1)
                {
                    largest = right;
                }

                if (largest == rIndex)
                {
                    return;
                }

                // process of reheaping / swapping
                var temp = input[rIndex];
                input[rIndex] = input[largest];
                input[largest] = temp;

                rIndex = largest;
            }
        }
    }
}

LANGUAGE:

DARK MODE: