插入排序,希尔排序,选择排序、快速排序详解以及消耗存储比较

20 篇文章 11 订阅
16 篇文章 0 订阅

插入排序,希尔排序,选择排序详解以及消耗存储比较

 

$arr=array(2,8,4,6,7,1,9,20,13); //待排序的数组
//插入排序
//从小到大
/*
思路
2,7,4,1
从第二个元素开始
1.比较7与2,因为7>2,故不移动位置
	2,7,4,1
2.比较4与7,因为4<7,故将第二个元素移动第三个元素的位置(向后移动一位)
	2,7,7,1
3.比较4与2的大小,因为4>2,故不移动位置,将4放到第二个位置上
	2,4,7,1
4.比较1与7的大小,因为1<7,将7移动到1的位置上(向后移动一位)
	2,4,7,7
   比较1与4的大小,1<4,将4向后移动一位
   2,4,4,7
   比较1与2的大小,1<2,将2向后移动一位
   2,2,4,7
   将4放置到第一位
   1,2,4,7
*/
/**
*params array $arr待排序数组
*/
function insertSort($arr){
	$len=count($arr);
	if($len ==1){
		return $arr;
	}
	for ($i=1; $i <$len ; $i++) { 
		$j=$i;
		$nextElement=$arr[$j];
		while ($j>0 && $nextElement<$arr[$j-1]) {
			$arr[$j]=$arr[$j-1];
			--$j;
		}
		$arr[$j]=$nextElement;
	}
	return $arr;
}
$startMemoryUsed=memory_get_usage();
var_dump(insertSort($arr));
$endMemoryUsed=memory_get_usage();
$usedMemory=($endMemoryUsed-$startMemoryUsed)/1024;
var_dump('插入排序消耗内存为:'.$usedMemory.'MB');

//希尔排序
/*思路:
关键是在于确定k值,即分组后每个组内元素个数
在程序设计中,一般最开始分两组,然后逐渐递减半
8 3 4 1 6 9 5 7
分两组k=8/2=4,每组四个
(8 3 4 1) (6 9 5 7)
最后一组的某一个位置上的数字与前面相对应位置上的数字比较
6与8比较
(6 3 4 1) (8 9 5 7)
9与3比较
(6 3 4 1) (8 9 5 7)
5与4比较
(6 3 4 1) (8 9 5 7)
7与1比较
(6 3 4 1) (8 9 5 7)

k=4/2=2,每组两个
(6 3) (4 1) (8 9) (5 7)
4与6比较
(4 3) (6 1) (8 9) (5 7)
1与3比较
(4 1) (6 3) (8 9) (5 7)
8与6比较
(4 1) (6 3) (8 9) (5 7)
9与3比较
(4 1) (6 3) (8 9) (5 7)
5与8比较
(4 1) (6 3) (8 9) (8 7)
5与6比较
(4 1) (6 3) (6 9) (8 7)
5与4比较
(4 1) (5 3) (6 9) (8 7)
7与9比较
(4 1) (5 3) (6 9) (8 9)
7与3比较
(4 1) (5 3) (6 7) (8 9)

k=2/2=1,每组1个
4 1 5 3 6 7 8 9
1与4比较
1 4 5 3 6 7 8 9
5与4比较
1 4 5 3 6 7 8 9
3与5比较
1 4 5 5 6 7 8 9
3与4比较
1 4 4 5 6 7 8 9
3与1比较
1 3 4 5 6 7 8 9
6与5比较
1 3 4 5 6 7 8 9
7与6比较
1 3 4 5 6 7 8 9
8与7比较
1 3 4 5 6 7 8 9
9与3比较
1 3 4 5 6 7 8 9
k=1/2=0,结束循环
*/
function shellSort($arr){
	$len=count($arr);//数组长度
	$k=(int)($len/2); //分组长度
	while($k>0){
		for ($i=$k; $i <$len ; $i++) { 
			$j=$i-$k;
			$curValue=$arr[$i];
			while ( $j>=0 && $arr[$j]>$curValue) {
				$arr[$j+$k]=$arr[$j];
				$j=$j-$k;
			}
			$arr[$j+$k]=$curValue;
		}
		$k=(int)($k/2);
	}
	return $arr;
}

$startMemoryUsed=memory_get_usage();
var_dump(shellSort($arr));
$endMemoryUsed=memory_get_usage();
$usedMemory=($endMemoryUsed-$startMemoryUsed)/1024;
var_dump('希尔排序消耗内存为:'.$usedMemory.'MB');

//选择排序
//思路:依次从线性表中找到最小的元素,插入到元素的最开始位置,然后从剩下的线性表中,找到最小元素,循环查找,一直到查处的列表为空为止。
/*
8 3 4 1 6 9 5 7
从该列表中找出最小数1,放置在第一个位置
1 3 4 8 6 9 5 7
从3 4 8 6 9 5 7找出最小元素3,放置在第二个位置
1 3 4 8 6 9 5 7
从4 8 6 9 5 7找出最小元素4,放置在第3个位置
1 3 4 8 6 9 5 7
从8 6 9 5 7找出最小元素5,放置在第4个位置
1 3 4 5 6 9 8 7
从8 6 9 5 7找出最小元素6,放置在第5个位置
1 3 4 5 6 9 8 7
从8 6 9 5 7找出最小元素7,放置在第6个位置
1 3 4 5 6 7 8 9
从8 6 9 5 7找出最小元素8,放置在第7个位置
1 3 4 5 6 7 8 9
从8 6 9 5 7找出最小元素9,放置在第8个位置
1 3 4 5 6 7 8 9
*/
//选择排序
function selectSort($arr){
	$len=count($arr);//数组长度
	for ($i=0; $i < $len; $i++) { 		
		$j=$i+1;
		$minIndex=$i;
		while ( $j<$len) {
			if($arr[$j]<$arr[$i]){
				$minIndex=$j;
			}
			++$j;
		}
		if($i !=$minIndex){
			//使用异或交互变量,节省内存消耗
			$arr[$minIndex]=$arr[$minIndex]^$arr[$i];
			$arr[$i]=$arr[$minIndex]^$arr[$i];
			$arr[$minIndex]=$arr[$minIndex]^$arr[$i];
		}
	}
	return $arr;
}

$startMemoryUsed=memory_get_usage();
var_dump(selectSort($arr));
$endMemoryUsed=memory_get_usage();
$usedMemory=($endMemoryUsed-$startMemoryUsed)/1024;
var_dump('选择排序消耗内存为:'.$usedMemory.'MB');

 

 

快速排序

/*
思路:从线性表中选取一个元素,设为T,然后将线性表该位置后面小于T的元素移到前面,
而前面大于T的元素移到后面,这样线性表分成了两部分(两个子表),T插入到分界线的位置处。
然后对分割后的子表继续进行分割,一直到所有的子表为空为止。

序列
2 4 9 3 6 7 1 5
选择2为基准,T=2,i=0,j=7
(1)从后面开始找到小于2的元素,移动到前面
比较2与5,5>2,然后比较2与1,1<2,将1放置到2的位置,j=6
1 4 9 3 6 7 1 5
(2)从前面开始查找大于2的元素,移动到后面
比较1与2,1<2,然后比较4与2,4>2,将4移动到后面1的位置i=2
1 4 9 3 6 7 4 5
(3)当i<j的时候,反复执行(1)~(2),最后i=j
(4)将第i个元素设置为T,故第一次排序后的序列如下
1 2 9 3 6 7 4 5
*/

 

function quickSort(&$arr,$start,$end){
	if($start<$end){
		$l=$start;
		$r=$end;
		$flag=$arr[$start];
		while($l<$r){
			while($arr[$r]>$flag && $r>$l){
			--$r;
			}
			if($r>$l){
				$arr[$l]=$arr[$r];
			}
			while($arr[$l]<$flag && $r>$l){
				++$l;
			}
			if($r>$l){
				$arr[$r]=$arr[$l];
			}
		}
		$arr[$r]=$flag;	
		//继续分割
		//$arr; $start ,$r-1
		//$arr $i+1,$end;
		quickSort($arr,$start,$r-1);
		quickSort($arr,$r+1,$end);
	}
}


$arr=array(2,4,9,3,6,7,1,5);
quickSort($arr,0,7);
var_dump($arr); 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值