Skip to content

Commit

Permalink
Merge pull request #116 from salehhashemi1992/heap-sort
Browse files Browse the repository at this point in the history
add heap sort to sort algorithms
  • Loading branch information
darwinz authored Sep 18, 2023
2 parents e967070 + e061398 commit 810f8fc
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
62 changes: 62 additions & 0 deletions Sorting/HeapSort.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
/**
* HeapSort Algorithm
*
* The HeapSort algorithm sorts an array by first transforming the array into a max heap and then
* iteratively swapping the maximum element from the heap with the last unsorted element
* and "heapifying" the heap again.
*
* @param array $arr
* @return array
* @throws \UnexpectedValueException
*/
function heapSort(array $arr): array
{
$n = count($arr);
if ($n <= 0) {
throw new \UnexpectedValueException('Input array must have at least one element.');
}

// Build heap
for ($i = $n / 2 - 1; $i >= 0; $i--) {
heapify($arr, $n, $i);
}

// Extract elements from heap one by one
for ($i = $n - 1; $i >= 0; $i--) {
// Swap
[$arr[0], $arr[$i]] = [$arr[$i], $arr[0]];

// Heapify the reduced heap
heapify($arr, $i, 0);
}

return $arr;
}

/**
* Ensures that the array satisfies the heap property
*
* @param array $arr
* @param int $n
* @param int $i
*/
function heapify(array &$arr, int $n, int $i): void
{
$largest = $i;
$left = 2 * $i + 1;
$right = 2 * $i + 2;

if ($left < $n && $arr[$left] > $arr[$largest]) {
$largest = $left;
}

if ($right < $n && $arr[$right] > $arr[$largest]) {
$largest = $right;
}

if ($largest !== $i) {
[$arr[$i], $arr[$largest]] = [$arr[$largest], $arr[$i]];
heapify($arr, $n, $largest);
}
}
26 changes: 26 additions & 0 deletions tests/Sorting/SortingTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require_once __DIR__ . '/../../Sorting/BubbleSort.php';
require_once __DIR__ . '/../../Sorting/BubbleSort2.php';
require_once __DIR__ . '/../../Sorting/CountSort.php';
require_once __DIR__ . '/../../Sorting/HeapSort.php';
require_once __DIR__ . '/../../Sorting/InsertionSort.php';
require_once __DIR__ . '/../../Sorting/MergeSort.php';
require_once __DIR__ . '/../../Sorting/QuickSort.php';
Expand Down Expand Up @@ -172,4 +173,29 @@ public function testQuickSortCipher()
$this->assertEquals($result1, $test1);
$this->assertEquals($result2, $test2);
}

public function testHeapSortPerformance()
{
$array = range(1, 1000000);
shuffle($array); // Randomize the order
$start = microtime(true);
heapSort($array);
$end = microtime(true);
$this->assertLessThan(1, $end - $start);
}

public function testHeapSortCipher()
{
$firstArray = [20, 16, -5, -8, 6, 12, 2, 4, -3, 9];
$expectedResultOne = [-8, -5, -3, 2, 4, 6, 9, 12, 16, 20];

$secondArray = [-6, 12, 14, 17, 5, 4, -9, 15, 0, -8];
$expectedResultTwo = [-9, -8, -6, 0, 4, 5, 12, 14, 15, 17];

$resultOne = heapSort($firstArray);
$resultTwo = heapSort($secondArray);

$this->assertEquals($expectedResultOne, $resultOne);
$this->assertEquals($expectedResultTwo, $resultTwo);
}
}

0 comments on commit 810f8fc

Please sign in to comment.