近几日有空,发现自己对一些基本的排序算法已经忘记,遂使用PHP来实现,复习一下。代码和注释如下:
class class_sort{
/**
* 直接选择排序
*/
public static function directSelectSort(&$data){
echo "直接选择排序开始:"."<br />";
$length=count($data);
for($i=0;$i<$length;$i++){
for($j=$i+1;$j<$length;$j++){
if ($data[$i]>$data[$j]) {
//$temp=$data[$i];
//$data[$i]=$data[$j];
//$data[$j]=$temp;
self::swap($data, $i, $j);
}
}
echo self::array2string($data).$i."<br />";
}
echo "直接选择排序结束"."<br />";
}
/**
* 改良的直接选择排序
*/
public static function directSelectSortEx(&$data){
echo "改良直接选择排序开始:"."<br />";
$length=count($data);
for($i=0;$i<$length;$i++){
$min=$i;
for($j=$i+1;$j<$length;$j++){
if ($data[$min]>$data[$j]) {
$min=$j;
}
}
if($min!=$i){
self::swap($data, $i, $min);
}
echo self::array2string($data).$i."<br />";
}
echo "改良直接选择排序结束"."<br />";
}
/**
* 堆排序
*/
public static function heapSort(&$data){
echo "堆排序开始:"."<br />";
$len=count($data);
//循环建堆
for($i=0;$i<$len-1;$i++){
self::buildHeap($data,$len-1-$i);
self::swap($data,0,$len-1-$i);
echo self::array2string($data).$i."<br />";
}
echo "堆排序结束"."<br />";
}
//建堆
private static function buildHeap(&$data,$lastIndex){
//从$lastIndex的父节点开始
if($lastIndex%2!=0){
$lastIndex++;
}
for ($j=$lastIndex/2;$j>=0;$j--){
//如果当前节点存在子节点
while ($j*2+1<=$lastIndex) {
//较大值的索引
$biggerIndex=$j*2+1;
//如果右子节点存在
if($biggerIndex<$lastIndex-1){
//比较左右子节点的大小
if($data[$biggerIndex]<$data[$biggerIndex+1]){
//较大值的索引总是指向较大的值
++$biggerIndex;
}
}
//如果$k节点的值小于其较大的字节点,交换
if ($data[$j]<$data[$biggerIndex]) {
self::swap($data, $j, $biggerIndex);
}else{
break;
}
}
}
}
/**
* 冒泡排序
* @param unknown $data
*/
public static function bubbleSort(&$data){
echo "冒泡排序开始:"."<br />";
$length=count($data);
for($i=0;$i<$length-1;$i++){
for ($j = $i+1; $j < $length; $j++) {
if($data[$j]<$data[$i]){
self::swap($data, $i, $j);
}
}
echo self::array2string($data).$i."<br />";
}
echo "冒泡排序结束"."<br />";
}
/**
* 快速排序[递归方法实现]
* @param unknown $data
*/
public static function quickSortRecursive(&$data){
echo "快速排序开始[递归]:"."<br />";
$length=count($data);
self::subQuickSortRecursive($data, 0, $length);
echo "快速排序结束[递归]"."<br />";
}
//用于递归的快速排序
private static function subQuickSortRecursive(&$data,$start,$end){
//需要排序
if($start<$end){
$low=$start;
$high=$end-1;
//以第一个元素作为分界值
$key=$data[$low];
while ($low<$high){
//从后往前找出小于关键数据的索引
while ($low<$high&&$data[$high]>=$key){
$high--;
}
//移动找出的值到低部
$data[$low]=$data[$high];
//从前往后找出大于关键值的索引
while ($low<$high&&$data[$low]<=$key){
$low++;
}
//交换到高部
$data[$high]=$data[$low];
}
//放入关键值
$data[$low]=$key;
echo self::array2string($data).$low."<br />";
self::subQuickSortRecursive($data, $start, $low);
self::subQuickSortRecursive($data, $low+1, $end);
}
}
/**
* 快速排序[非递归实现][借用递归实现的原理,使用栈来实现]
* @param unknown $data
*/
public static function quickSort(&$data){
echo "快速排序开始[非递归]:"."<br />";
$stack=array();
$length=count($data);
$low=0;
$high=$length-1;
if ($low<$high) {
$mid=self::subQuickSort($data, $low, $high);
if ($low<$mid-1) {
array_push($stack, $low);
array_push($stack,$mid-1);
}
if ($mid+1<$high) {
array_push($stack, $mid+1);
array_push($stack,$high);
}
while (!empty($stack)) {
$q=end($stack);
array_pop($stack);
$p=end($stack);
array_pop($stack);
$mid=self::subQuickSort($data, $p, $q);
if ($p<$mid-1) {
array_push($stack, $p);
array_push($stack,$mid-1);
}
if ($mid+1<$q) {
array_push($stack,$mid+1);
array_push($stack,$q);
}
}
}
echo "快速排序结束[非递归]"."<br />";
}
//非递归
private static function subQuickSort(&$data,$start,$end){
$i=$start;
$j=$end;
//以第一个元素作为分界值
$key=$data[$i];
while ($i<$j){
//从后往前找出小于关键数据的索引
while ($i<$j&&$data[$j]>=$key){
$j--;
}
//移动找出的值到低部
$data[$i]=$data[$j];
//从前往后找出大于关键值的索引
while ($i<$j&&$i<$j&&$data[$i]<=$key){
$i++;
}
//交换到高部
$data[$j]=$data[$i];
}
//放入关键值
$data[$i]=$key;
echo self::array2string($data).$i."<br />";
return $i;
}
/**
* 插入排序
* @param unknown $data
*/
public static function insertSort(&$data){
echo "插入排序开始:"."<br />";
$length=count($data);
for ($i = 1; $i < $length; $i++) {
//保存索引$i处的值,防止整体后移时丢失
$temp=$data[$i];
if ($temp<$data[$i-1]) {
/*for ($j=$i-1;$j>=0&&$data[$j]>$temp;$j--){
$data[$j+1]=$data[$j];
}*/
$j=$i-1;
while ($j>=0&&$data[$j]>$temp) {
$data[$j+1]=$data[$j];;
$j--;
}
$data[$j+1]=$temp;
}
echo self::array2string($data).$i."<br />";
}
echo "插入排序结束"."<br />";
}
/**
* 折半插入排序[插入排序改良]
* @param unknown $data
*/
public static function binaryInsertSort(&$data){
echo "折半插入排序开始:"."<br />";
$length=count($data);
for ($i = 1; $i < $length; $i++) {
//保存索引$i处的值,防止整体后移时丢失
$temp=$data[$i];
$low=0;
$high=$i-1;
while ($low<=$high) {
if(($low+$high)%2==0){
$mid=($low+$high)/2;
}else{
$mid=($low+$high+1)/2;
}
if($data[$mid]<$temp){
$low=$mid+1;
}else{
$high=$mid-1;
}
}
//整体向后移yiwei
for ($j = $i; $j > $low; $j--) {
$data[$j]=$data[$j-1];
}
$data[$low]=$temp;
echo self::array2string($data).$i."<br />";
}
echo "折半插入排序结束"."<br />";
}
/**
* 交换
*/
private static function swap(&$data,$i,$j){
$tmp=$data[$i];
$data[$i]=$data[$j];
$data[$j]=$tmp;
}
/**
* 数组转字符串输出
*/
public static function array2string($array){
$str="[";
foreach ($array as $value) {
$str.=$value.",";
}
$str=mb_substr($str, 0,(mb_strlen($str)-1))."]";
return $str;
}
}