数组排序

冒泡排序

<?php
$arr1 = array(5,9,2,6,4,7,365,69,5,62,1);						//数组共有10个元素

for($j=0,$lenght=count($arr1);$j<$lenght;$j++) {
	for ($i = 0, $lenght = count($arr1); $i < $lenght-1-$j; $i++) {			
//因为是向高一位比较,所以比较进行到第九个元素,即下标为8
//随着比较次数的增加,每次需要比较的元素减少一个
		if ($arr1[$i] > $arr1[$i + 1]) {       //比较左右两数字的大小
			$value = $arr1[$i + 1];            //如果左边的数字更大,交换两数字
			$arr1[$i + 1] = $arr1[$i];
			$arr1[$i] = $value;
		}
	}
}
echo '<pre>';
print_r ($arr1);

 

选择排序:(相较于冒泡交换次数更少)

假设第一个元素为最小元素,保存下标

寻找右侧元素,如果有更小的元素,重新保存其下标

如果下标改变,则交换两元素

标记下一个元素,继续执行以上步骤,直至最后一个元素

<?php
$arr1 = array(7,8,9,6,5,4,1,2,3);
				//1、首先确定需要交换多少次,即数组长度
for($i=0,$lenght=count($arr1);$i<$lenght;$i++){
				//2、假设第一个元素就是最小的
	$min=$i;
				//3、寻找是否有更小的元素
	for($j=$i+1;$j<$lenght;$j++){
				//4、比较当前元素和最小的元素
		if($arr1[$j]<$arr1[$min]){
				//说明当前的值不合适
			$min=$j;
		}
	}

				//5、交换起初值和实际最小值
	if($min!= $i){     //判断当前下标是否发生改变
		$value=$arr1[$min];
		$arr1[$min]=$arr1[$i];
		$arr1[$i]=$value;
	}

}
echo '<pre>';
print_r ($arr1);

 

插入排序

把一个数据插入到已经排好序的有序数据中,从而得到一个新的(元素个数加一的)数据。

1、认定第一个元素已经排好序;

2、假定取出第二个元素,作为待插入数据;

3、与已经排好序的数组的最右侧元素开始进行比较

4、如果后面的小于前面的,说明前面已经排好序的数组元素不在对的位置(向后移一位),然后让新的元素填充进去,继续向前比。

5、重复前面的步骤,直到当前元素插入到正确位置。

6、重复以上步骤,直到所有的数组元素都插入到正确位置。

<?php
//插入排序
$arr = array(2,5,8,9,6,3);
			//1、确定要插入多少回(假设一个数组一次性插入到对的位置,同时第一个位置是假设对的。
for($i=1,$lenght=count($arr);$i<$lenght;$i++){
			//2、取出当前要插入的元素的值
	$temp=$arr[$i];
	$change=false;//标记是否需要换位
			//3、让该数据与前面已经排好序的数组元素比较(挨个比较),直到对的位置
	for($j=$i-1;$j>=0;$j--){
  			//4、比较
		if($arr[$j]>$temp){ //说明当前要插入的元素,比已经排好序的数列的最后一个元素小,交换位置
			$arr[$j+1]=$arr[$j];
			//插入元素小于前面元素才会执行,则需要换位,打开change
			$change=true;//$arr[$j]=$temp;
		}
		else{         //说明当前待插入元素比前面的元素大,不需要换位
			break;
		}
	}
	if($change){
	$arr[$j+1]=$temp;//j-1判断失败后才会进入这一步,所以需要j+1获得原值
	}
}
echo '<pre>';
print_r($arr);

 

快速排序:

对冒泡排序的改进,利用递归函数

1、从数组中选出第一个元素,作为参照对象;

2、将数组中剩余元素与参照对象进行比较,更小的放在一个数组,更大的放在另外一个数组;

3、将剩余数组多次重复进行以上操作;

4、回溯最小数组(数组中仅有一个元素)。

<?php
//快速排序
$arr1= array(5,4,7,8,5,2,3,6,9,8,7,4,5,6,3,2,1);
function quickSort($arr){
	$len = count($arr);
	if($len <=1){
		return $arr;
	}
	$left=$right= array();
	for($i=1;$i<$len;$i++){     //第一个元素作为比较,所以从第二个元素开始
		if($arr[$i]<$arr[0]){
			$left[] =$arr[$i];
		}
		else{
			$right[]=$arr[$i];
		}
	}
	//排序$left和$right;   递归点
	$left = quickSort($left);
	$right = quickSort($right);
	//合并三个数组
	return array_merge($left,(array)$arr[0],$right);
}

echo '<pre>';
print_r(quickSort($arr1));

 

归并排序

采用分治法,将已有序的子序列合并,得到完全有序的序列。

即先使每个子序列(仅含有1-2个元素)有序,再使子序列段间有序。

将两个有序数列合并成一个有序数列,成为二路归并:

<?php
            //PHP二路归并
$arr1 = array(1,4,7);
$arr2 = array(2,5,8);
$arr3 = array();            事先开辟一个空数列用于归并空间

while(count($arr1) && count($arr2)){  //判断两组数列是否为空,若某一组为空,则跳出循环
$arr3[]= $arr1[0]<$arr2[0] ? array_shift($arr1) : array_shift($arr2);
//三目运算,如果数组一中首位元素更小,则从数组中取出,否则取出数组二首位元素
}
    //合并三组数列
print_r($arr3,$arr1,$arr2);    //此时两组数列谁在前已经无关紧要,因为其中一组必为空数列

思路:

1、将数组拆分成两个数组

2、重复步骤1,把数组拆分成最小单元

3、申请空间,作为合并空间

4、利用二路归并

<?php
													//归并排序
$arrTest=array(98,98,7,89,4,84,64,56,4654,65,42,1,21,3);
function arraySort($arr){
	$len = count($arr);      	 					//获取数列长度
	 if ($len<=1){return $arr;}
	 												//把数组分开
	$middle = floor($len/2);
	 $left = array_slice($arr,0,$middle);
	 $right = array_slice($arr,$middle);
													 //递归点:此时可能数列还不是单个元素的数列
	$left = arraySort($left);
	$right = arraySort($right);
													 //假设此时都已经是有序数列,进行二路归并
	$m = array();									//为最终序列开辟空间存放
	while(count($left) && count($right)){ 		//判断两个数列中是否有空数列
	$m[] = $left[0] < $right[0] ? array_shift($left) : array_shift($right);
	}
	return array_merge($m,$left,$right);
}
echo '<pre>';
print_r(arraySort($arrTest));

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值