<?php /** * 内部排序:将待排序序列放在内存中排序,适合于不太大的序列 */ /* * 策略模式实现如下 */ //排序接口 interface Isort{ public function inSort($arr); } /*================冒泡排序=====================*/ /*冒泡排序:时间复杂度O(n^2),稳定排序*/ class BubbleSort implements Isort{ public function inSort($arr){ $len = count($arr); for ($i=0;$i<$len-1;$i++){ for($j=0;$j<$len-$i-1;$j++){ if($arr[$j]>$arr[$j+1]){ $tmp = $arr[$j]; $arr[$j] = $arr[$j+1]; $arr[$j+1] = $tmp; } } } return $arr; } } //冒泡的改进算法 class BubbleSortB implements Isort{ public function inSort($arr){ $len = count($arr); for ($i=0;$i<$len-1;$i++){ $flag = 1; for($j=0;$j<$len-$i-1;$j++){ if($arr[$j]>$arr[$j+1]){ $flag = 0; $tmp = $arr[$j]; $arr[$j] = $arr[$j+1]; $arr[$j+1] = $tmp; } } if($flag==1)break; } return $arr; } } //沉底,往下沉 class BubbleSortA implements Isort{ public function inSort($arr){ $len = count($arr); for ($i=0;$i<$len-1;$i++){ for($j=$len-1;$j>$i;$j--){ if($arr[$j]>$arr[$j-1]){ $tmp = $arr[$j]; $arr[$j] = $arr[$j-1]; $arr[$j-1] = $tmp; } } } return $arr; } } /*======================END===========================*/ /*======================选择排序=====================*/ //选择排序,时间复杂度O(n^2),不稳定的 class SelectSort implements Isort{ public function inSort($arr){ $len = count($arr); for($i=0;$i<$len-1;$i++){ $k = $i; for($j=$i+1;$j<$len;$j++){ if($arr[$j]<$arr[$k]){ $k = $j; } } if($k!=$i){ $tmp = $arr[$k]; $arr[$k] = $arr[$i]; $arr[$i] = $tmp; } } return $arr; } } /*==================END===================*/ /*=======================快速排序==========================*/ //不稳定的,时间复杂度理想O(n*logn),最坏O(n^2) class QuickSort implements Isort{ public function inSort($arr){ $len = count($arr); if($len <= 1){//注意退出条件,不止等于1,小于1 同样考虑 return $arr; } $key = $arr[0]; $left_arr = array(); $right_arr = array(); for ($i=1;$i<$len;$i++){ if($arr[$i]>$key){ $right_arr[] = $arr[$i]; }else{ $left_arr[] = $arr[$i]; } } $res = array_merge($this->inSort($left_arr),array($key),$this->inSort($right_arr)); return $res; } } /*=========================END==============================*/ /** * 插入排序,稳定的,时间复杂度O(n^2) */ class InsertSort implements Isort{ public function inSort($arr){ $len = count($arr); for($i=1;$i<$len;$i++){ $tmp = $arr[$i]; $key = $i-1; while($key>=0&&$tmp<$arr[$key]){//条件顺序不能颠倒 $arr[$key+1] = $arr[$key]; $key--; } $arr[$key+1] = $tmp; } return $arr; } } /** * *希尔排序,不稳定的,时间复杂度O(n^1.5) */ class ShellSort implements Isort{ public function inSort($arr){ $len = count($arr); $dk = floor($len/2);//初始跨度 while($dk>0){ for($i=$dk;$i<$len;$i++){ $tmp = $arr[$i]; $key = $i-$dk; while ($key>=0&&$tmp<$arr[$key]){//每次在跨度分组内进行直接插入排序 $arr[$key+$dk] = $arr[$key]; $key = $key-$dk; } $arr[$key+$dk] = $tmp; } $dk = floor($dk/2); } return $arr; } } /** * 堆排序:不稳定的,时间复杂度O(n*logn) * */ class HeapSort implements Isort{ public function inSort($arr){ $len = count($arr); $this->initHeap($arr); for($end=$len-1;$end>0;$end--){ $tmp = $arr[$end]; $arr[$end] = $arr[0]; $arr[0] = $tmp; $this->adjustHeap($arr,0,$end-1); } return $arr; } private function initHeap(&$arr){ $len = count($arr); for($start=floor($len/2)-1;$start>=0;$start--){ $this->adjustHeap($arr,$start,$len-1); } } private function adjustHeap(&$arr,$start,$end){ $max = $start; $lchild = 2*($start+1)-1; $rchild = 2*($start+1); if($lchild<=$end){ if($arr[$lchild]>$arr[$max]){ $max = $lchild; } if($rchild<=$end&&$arr[$rchild]>$arr[$max]){ $max = $rchild; } } if($max!=$start){ $tmp = $arr[$max]; $arr[$max] = $arr[$start]; $arr[$start] = $tmp; $this->adjustHeap($arr, $max, $end); } } } /** * 归并排序:稳定的,时间复杂度O(n*logn),最好,最坏都是这个 */ class MergeSort implements Isort{ public function inSort($arr){ $len = count($arr); $this->mSort($arr,0,$len-1); return $arr; } //核心,对数组中某一段进行排序 private function mSort(&$arr,$low,$high){ if($low<$high){ $mid = floor(($low+$high)/2); $this->mSort($arr, $low, $mid); $this->mSort($arr, $mid+1, $high); $this->mergeArray($arr, $low, $mid, $high); } } private function mergeArray(&$arr,$low,$mid,$high){ $i = $low; $j = $mid+1; while ($i<=$mid&&$j<=$high){ if($arr[$i]<$arr[$j]){ $tmp[] = $arr[$i++]; }else{ $tmp[] = $arr[$j++]; } } while($i<=$mid){ $tmp[] = $arr[$i++]; } while($j<=$high){ $tmp[] = $arr[$j++]; } $len = count($tmp); for($k=0;$k<$len;$k++){ $arr[$low+$k] = $tmp[$k]; } } } class Context{ public $method; public function __construct(Isort $method){ $this->method = $method; } public function doSort($arr){ $arr = $this->method->inSort($arr); return $arr; } } $arr = array(6,3,1,2,7,4,5,0,-2,-1,0); $m = new context(new MergeSort()); $arr = $m->doSort($arr); print_r($arr); ?>