HeapSort is an sort algorithms, using heap tree(Full Binary Tree) for help.
Implementing this sort should execute three steps
1. Adjust an entire array to a heap tree(big heap tree for ascending, small heap tree for descending sort)
2. Get the root of the heap tree arr[0] and swap it with last one of the no-sort array, that will consider as the item of the sort array.
3. Re-adjust the new no-sort array, till the no-sort array has only one item.
Code is below:
///
<summary>
/// Heap Sort
/// </summary>
/// <param name="arr"></param>
public static void HeapSort( int[] arr)
{
if (arr == null)
{
throw new ArgumentNullException();
}
// Adjust array, make it as big heap
for ( int i = arr.Length / 2 - 1; i >= 0; i--)
{
HeapAdjust(arr, i, arr.Length);
}
for ( int i = arr.Length - 1; i > 0; i--)
{
// Swap the first one with last one, both of which in the left no-sort sub array
// Generated no-sort subarray (a[0]-a[i-1]) and sort subarray(a[i-1]-a[arr.Length-1]).
int temp = arr[i];
arr[i] = arr[ 0];
arr[ 0] = temp;
// Re-adjust left no-sort subarray to a heap
HeapAdjust(arr, 0, i);
}
}
/// <summary>
/// Adjust array to a big heap
/// </summary>
/// <param name="arr"></param>
/// <param name="i"> sub-heap's root index </param>
/// <param name="len"> sub-array's length </param>
private static void HeapAdjust( int[] arr, int i, int len)
{
if (arr == null)
{
throw new ArgumentNullException();
}
if (len > arr.Length || i > len - 1 || i < 0)
{
throw new ArgumentOutOfRangeException();
}
for ( int child = 2 * i + 1; child < len; i = child, child = 2 * i + 1)
{
// Choose big one of children to compare with parent
if (child < len - 1 && arr[child] < arr[child + 1])
{
child++;
}
// if the big child is greater than its parent, then swap them.
if (arr[i] < arr[child])
{
int temp = arr[i];
arr[i] = arr[child];
arr[child] = temp;
}
// if not, break the loop
else
{
break;
}
}
}
/// Heap Sort
/// </summary>
/// <param name="arr"></param>
public static void HeapSort( int[] arr)
{
if (arr == null)
{
throw new ArgumentNullException();
}
// Adjust array, make it as big heap
for ( int i = arr.Length / 2 - 1; i >= 0; i--)
{
HeapAdjust(arr, i, arr.Length);
}
for ( int i = arr.Length - 1; i > 0; i--)
{
// Swap the first one with last one, both of which in the left no-sort sub array
// Generated no-sort subarray (a[0]-a[i-1]) and sort subarray(a[i-1]-a[arr.Length-1]).
int temp = arr[i];
arr[i] = arr[ 0];
arr[ 0] = temp;
// Re-adjust left no-sort subarray to a heap
HeapAdjust(arr, 0, i);
}
}
/// <summary>
/// Adjust array to a big heap
/// </summary>
/// <param name="arr"></param>
/// <param name="i"> sub-heap's root index </param>
/// <param name="len"> sub-array's length </param>
private static void HeapAdjust( int[] arr, int i, int len)
{
if (arr == null)
{
throw new ArgumentNullException();
}
if (len > arr.Length || i > len - 1 || i < 0)
{
throw new ArgumentOutOfRangeException();
}
for ( int child = 2 * i + 1; child < len; i = child, child = 2 * i + 1)
{
// Choose big one of children to compare with parent
if (child < len - 1 && arr[child] < arr[child + 1])
{
child++;
}
// if the big child is greater than its parent, then swap them.
if (arr[i] < arr[child])
{
int temp = arr[i];
arr[i] = arr[child];
arr[child] = temp;
}
// if not, break the loop
else
{
break;
}
}
}