冒泡排序
思路分析:前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即,每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。所以每一次循环就将确认一个最大值放在数组尾部。
测试运行时间(0.000331)
$arr=array(1,43,54,62,21,66,32,78,36,76,39); 长度为11
function sortArray($arr){
$count = count($arr);
for ($i=1; $i < $count; $i++) { //该层循环控制 需要冒泡的轮数
for ($k=0; $k < $count-$i; $k++) { //该层循环用来控制每轮 冒出一个数 需要比较的次数
//为什么用$count-$i 因为外层每次循环都会把最大的元素放在了数组最后一位,所以就可以少比较$i;
if($arr[$k] > $arr[$k+1]){
$tmp = $arr[$k]; //如果前面的大于后面就将2个调换位置
$arr[$k] = $arr[$k+1];
$arr[$k+1] = $tmp;
}
}
}
return $arr;
}
内部情况如下:
第一次循环 $arr = array( 1,42, 53,21,62,32,66,36,76,39,78); 把最大的放在最后一位
第二次循环 $arr = array( 1,42,21,53,32,62,36,66,39,76,78); 把最大的放在最后一位,此时最大循环到(< $count-$i)即8 最后的比较就是$arr[8](76) 和 $arr[9](39) 然后交换位置
以此类推 最后完成从小到大排序。
选择排序
思路分析:在要排序的一组数中,选出最小的一个数与第一个位置的数交换。然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。
测试运行时间(0.000193)
function selectArray($arr){
$count = count($arr);
//双重循环完成,外层控制轮数,内层控制比较次数
for ($i=0; $i < $count -1; $i++) { //$count-1 因为每一次外层循环都将确认一个最小值放在数组首部
$p = $i; //先假设最小的值的位置
for ($j=$i+1; $j < $count; $j++) { //$i+1 进行比较时$arr[$i]和自己之后的元素进行比较 因为外层每一次循环都已经确定了最小的一个 跟之前的元素就不需要比了
if($arr[$p] > $arr[$j]){
$p = $j; //比较,发现更小的,记录下最小值的位置;并且在下次比较时采用已知的最小值进行比较
}
}
if($p != $i){ //已经确定了当前的最小值的位置,保存到$p中。如果发现最小值的位置与当前假设的位置$i不同,则位置互换即可。
$tmp = $arr[$p];
$arr[$p] = $arr[$i];
$arr[$i] = $tmp;
}
}
return $arr;
}
内部情况如下:
第一次循环 $arr = array( 1,42,53,62,21,66,32,78,36,76,39); 把最小的放在第一位
第二次循环 $arr = array(1,21,54,62,43,66,32,78,36,76,39); 把最小的放在第一位,此时循环从$i=1开始 所以第一位为$arr[1](42),找到最小的然后交换位置。
以此类推 最后完成从小到大排序。
插入排序
思路分析:在要排序的一组数中,假设前面的数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。
测试运行时间(0.000268)
function insertArray($arr){
$count = count($arr);
for ($i=1; $i < $count; $i++) { //内层循环控制,比较并插入
$tmp = $arr[$i];
for ($j=$i-1; $j >= 0; $j--) { //$arr[$i] 每次都与自己前面的元素进行比较
if($tmp < $arr[$j]){ //发现插入的元素要小,交换位置,将后边的元素与前面的元素互换
$arr[$j+1] = $arr[$j];
$arr[$j] = $tmp;
}else{
break;//如果碰到不需要移动的元素,由于是已经排序好是数组,则前面的就不需要再次比较了。
}
}
}
return $arr;
}
内部情况如下:
第一次循环 $arr = array( 1,42,53,62,21,66,32,78,36,76,39); $i=1,所以将下标1之前的排序 1,42
第二次循环 $arr = array( 1,42,53,62,21,66,32,78,36,76,39); $i=2,所以将下标2之前的排序 1,42,53
第三次循环 $arr = array( 1,42,53,62,21,66,32,78,36,76,39); $i=3,所以将下标3之前的排序 1,42,53,62
第四次循环 $arr = array( 1,21,42,53,62,66,32,78,36,76,39); $i=4,所以将下标4之前的排序 1,21,42,53,62
以此类推 最后完成从小到大排序。
快速排序
思路分析:选择一个基准元素,通常选择第一个元素或者最后一个元素。通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素。此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。
测试运行时间(0.000329)
function quickArray($arr){
if(empty($arr[1])){
return $arr;
}
$mid = $arr[0];
$count = count($arr);
$minArr = array();
$maxArr = array();
for ($i=0;$i<$count;$i++){
if($arr[$i] < $mid){
$minArr[] = $arr[$i]; //比中间值小的放入min数组
}
if($arr[$i] > $mid){
$maxArr[] = $arr[$i]; //比中间值大的放入min数组
}
}
$minArr = $this->quickArray($minArr); //将小的数组递归找出最小的
$minArr[] = $mid; //将中间值放入min数组中
$maxArr = $this->quickArray($maxArr);
$arr = array_merge($minArr,$maxArr); //组合数组
return $arr;
}