MoyaSystem

もやしです。

Quick sort, Merge sort and Heap sort in PHP

<?php

/**
 * QUICK SORT
 */
function quick_sort($a){

	if(sizeof($a) <= 1){
		return $a;
	}

	$left_a = [];
	$right_a = [];
	$pivot = array_pop($a);

	foreach($a as $e){
		if($e <= $pivot){
			array_push($left_a, $e);
		}else{
			array_push($right_a, $e);
		}
	}

	$left_a = quick_sort($left_a);
	$right_a = quick_sort($right_a);
	return array_merge($left_a, [$pivot], $right_a);
}


/**
 * MERGE SORT
 */
function merge_sort($a){
	$left_a = [];
	$right_a = [];

	if(sizeof($a) <= 1){
		return $a;
	}

	$middle = (int)sizeof($a)/2;

	$left_a = array_slice($a, 0, $middle);
	$right_a = array_slice($a, $middle);

	$left_a = merge_sort($left_a);
	$right_a= merge_sort($right_a);

	return merge($left_a, $right_a);
}

function merge($left, $right){
	$result = [];
	while(sizeof($left) > 0 && sizeof($right) > 0){
		$l = $left[0];
		$r = $right[0];

		if($l <= $r){
			array_push($result, array_shift($left));
		}else{
			array_push($result, array_shift($right));
		}
	}

	while(sizeof($left) > 0){
		array_push($result, array_shift($left));
	}

	while(sizeof($right) > 0){
		array_push($result, array_shift($right));
	}

	return $result;
}


/**
 * HEAP SORT
 */
function heap_sort($a){
	$result = $a;

	// create heap
	for($i=0;$i<sizeof($a);$i++){
		$result = upheap($result, $i);
	}

	for($i=sizeof($a)-1;$i>0;$i--){
		// put the first element into sorted list area
		$result = swap($result, 0, $i);
		$result = downheap($result, $i);
	}

	return $result;
}

function swap($arr, $a, $b){
	$temp = $arr[$a];
	$arr[$a] = $arr[$b];
	$arr[$b] = $temp;
	return $arr;
}

// make arr[0] - arr[$n] heap
function upheap($arr, $n){
	while($n > 0){
		// get parent value
		$m = (int)(($n+1)/2-1);
		if($arr[$m] < $arr[$n]){
			// if a child is bigger than its parent, swap them
			$arr = swap($arr, $m, $n);
		}else{
			// if $arr is valiable heap, break
			break;
		}
		// check parent's value
		$n = $m;
	}
	return $arr;
}

// make arr[0] - arr[$n-1] heap
function downheap($arr, $n){
	$parent_to_swap = 0;
	$child_to_swap = 0;

	while(true){
		$l_child = (int)($parent_to_swap+1)*2-1;
		$r_child = (int)($parent_to_swap+1)*2;

		// if left child overflow the target, break
		if($l_child >= $n){
			break;
		}

		// Is left child bigger than its parent?
		if($arr[$l_child] > $arr[$child_to_swap]){
			$child_to_swap = $l_child;
		}

		// Is right child within target and bigger than its parent?
		if($r_child < $n && $arr[$r_child] > $arr[$child_to_swap]){
			$child_to_swap = $r_child;
		}

		// no need to swap, break
		if($child_to_swap === $parent_to_swap){
			break;
		}

		$arr = swap($arr, $child_to_swap, $parent_to_swap);

		// continue checking with the swaped child as a new parent
		$parent_to_swap = $child_to_swap;
	}

	return $arr;
}



$arr = [5,3,2,9,7,0,1,4,6,8];
var_dump(quick_sort($arr));
echo "<br/>";
var_dump(merge_sort($arr));
echo "<br/>";
var_dump(heap_sort($arr));
?>