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

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

  

posted @ 2014-12-01 16:25  tai君  阅读(216)  评论(0编辑  收藏  举报