内部排序小结(策略模式实现)

<?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);

?>

  

你可能感兴趣的:(策略模式)