php 常用四种排序 冒泡,选择,插入,快排

Posted babytuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php 常用四种排序 冒泡,选择,插入,快排相关的知识,希望对你有一定的参考价值。

---恢复内容开始---

1冒泡排序。  【为描述方便,例子全面为升序排列】
 简述:假设数组有10个数字,从左向右。依次比较,如果前者大于后者,则两两交换。每一轮将冒泡一个最大数出来,依次循环,完成排序
 流程描述
-- 第一次  a[0] 与 a[1]  比如果 a[0] > a[1]  则 a[0] 与 a[1] 交换,然后 a[1] 与 a[2] 交换,依次到  a[8] 与 a[9]  交换。  此轮过后  a[9] 必为  a[0-9]  中的最大值。
 第二次(此时 a[9]以是最大值)  a[0] 与 a[1]  比如果 a[0] > a[1]  则 a[0] 与 a[1] 交换,然后 a[1] 与 a[2] 交换,依次到  a[7] 与 a[8]  交换。  此轮过后  a[8] 必为  a[0-8]  中的最大值。
    第三次(此时 a[9]以是最大值,a[8]次大)  a[0] 与 a[1]  比如果 a[0] > a[1]  则 a[0] 与 a[1] 交换,然后 a[1] 与 a[2] 交换,依次到  a[6] 与 a[7]  交换。  此轮过后  a[7] 必为  a[0-7]  中的最大值。
-------------- 如此反复,一次冒泡一个最大值出来。


//冒泡排序代码示例
  public function bubbleSort($arr){  //冒泡排序
        $len = sizeof($arr);
        for( $i = 0; $i< $len - 1; $i++){    //冒第几个泡

            for( $j = 0; $j < $len - $i - 1 ; $j++){  //未冒完泡的依次比较,找出最大值
                if( $arr[$j] > $arr[$j+1]){
                    $arr =    swap($arr , $j , $j+1);
                }
            }
        }
        return $arr;
    }


    //将数组的第 i j 位互换。  //后面代码略
    public function swap($arr , $i , $j){  //
        $temp = $arr[$i];
        $arr[$i] = $arr[$j];
        $arr[$j] = $temp;
        return $arr;
    }

 

 

2选择排序
简述,假设数组有10个数字,从左向右 1 到9  每个与右边的所有数进行比较,找出右侧最小的,并与之替换。   
流程描述
--  第一次 a[0] 逐个与  a[1] - a[9] 比对,找到最小值,然后 a[0]与a[0-9]中的最小值进行替换。替换后 a[0] 为数组最小值 (如果0 正好是最小,则不替换 )
    第二次  此时a[0],以是最小值,进行下一步。a[1] 逐个与  a[2] - a[9] 比对,找到最小值,然后 a[1]与a[1-9]最小的进行替换。 
    第三次   此时a[0],以是最小值,a[1] 为数组次小值(前两个元素已排好序)   a[2] 逐个与  a[3] - a[9] 比对,找到最小值,然后 a[2]与那个a[2-9]最小值的进行替换。 
   ............... 依次循环,完成排序。

//选择排序代码示例
function selectSort($arr){  //
        $len = sizeof($arr);
        for( $i = 0; $i< $len - 1; $i++){  //从左向右遍历,每次找出 i 位的最小值.
$minIndex = $i; for( $j = $i+1; $j < $len ; $j++){ //遍历 i 右边的不断的找出最小值。 if( $arr[$minIndex] > $arr[$j]){ $minIndex = $j; } } //位置交换 if( $i != $minIndex){ //把当次最左边的与向右查找的最小值进行替换。 $arr = $this->swap( $arr , $i , $minIndex);; } } return $arr; }


3 快速排序 (重点)
  简述:
设置一个基数,然后对数组进行左右切割。(左边比基数小,右边大于等于基数) ,然后再对左边数组做上述操作。  最后将左  数组  基数  右数据 进行归并
 

 //快速排序算法   
 public function quickSort($arr){
        $len = sizeof($arr);
        if( $len <=1 ) return $arr;

        $base = $arr[0];  //基数

        $l_arr = array();  //左边数组
        $r_arr = array();  //右边数组
        for($i = 1;$i<$len ; $i++){
            if( $arr[$i] < $base){
                $l_arr[]= $arr[$i];
            }else{
                $r_arr[]=$arr[$i];
            }
        }
        $l_arr = quickSort($l_arr);
        $r_arr = quickSort($r_arr);
        return array_merge($l_arr , array($base) , $r_arr);
    }

 

 

4 插入排序 (附带介绍,可以略过)
简述,假设数组有10个数字,从数组第二个开始,  每次向左比较【左边已是一个有序数组】依次向左找到自己的位置,一个一个比。
受制于语言能力,写得很饶口。

--  第一次 a[1]  与 a[0] 比,如果a[1] < a[0]   则 将a[0] 数据移至 a[1] 位   将 a[1] 的值插入到 a[0]位置上。  

-- 第二次  a[2] (待插入值) 与 a[0] ,  a[1] (已经有序)  如果a[2](待插入值)  > a[1]  则 a[2] (待插入值) 不动。  如果小于a[1]  则 将原  a[1] 数值移到 a[2] 中,a[2](待插入值)  的值放入到  a[1]中。  再与 a[0] 比,如果大于 a[0] 则  a[0]值放入到 a[1] 中。

public function insertSort($arr){
        $len = sizeof($arr);
        for( $i = 1; $i< $len ; $i++){
            $temp = $arr[$i];
       for( $j = $i-1; $j>=0; $j--){ //针对一个有序数据,依次找插入位
                if($temp < $arr[$j]){ //逐个插入。
                    $arr[$j+1] = $arr[$j];
                    $arr[$j] = $temp;
                }else{
                    break;
                }
            }
        }
        return $arr;
    }

 

写在最后:要对大量数据,有量级的概念。 快排的复杂度是  O( N log N)  ,冒泡排序是 O(N平方)
仅以1万个数为例。  快排复杂度是  10000 * Log2 10000 约为  13* 万    ,冒泡则是 1亿。  相差约800倍性能。
如果是10万个  快排则是 10万 * log2  100000 约为 170万   而冒泡则是100亿。  瞬间差出约7000 位。

而10万条数据,在真实场景下,真的不多。

如果说感受不明显,就跑跑代码体验下。

/**性能调试。*/
function bench_profile($starttime , $flag = ‘‘){
    $endtime = explode(‘ ‘,microtime());
    $thistime = $endtime[0]+$endtime[1]-($starttime[0]+$starttime[1]);
    $thistime = round($thistime,3);
    return  $flag."-bench:".$thistime." sec";
}


  $start_time = explode(‘ ‘,microtime());
        echo     bench_profile($start_time)."<br/>";
            $arr = [];
            for($i=0;$i<10000;$i++){
                $arr[]= rand(1,100000);
            }
            $arr_insert = quickSort($arr);
        echo   bench_profile($start_time);
//1w条跑完时间 -bench:0.053 sec    冒泡算法。  约 45 秒
//10w条跑完时间 -bench:0.77 sec    冒泡算法    约 一个半小时。
//100万条,跑完时间  16秒。 这时需要放开内存限制  ini_set("memory_limit",-1) 。  这时还用冒泡算法。 明天再来看结果。

 

技术分享图片

 























以上是关于php 常用四种排序 冒泡,选择,插入,快排的主要内容,如果未能解决你的问题,请参考以下文章

总结4种常用排序(快排选择排序冒泡排序插入排序)

总结4种常用排序(快排选择排序冒泡排序插入排序)

Java 常用算法(冒泡选择插入快排)

php常用四种算法

php四种基础算法:冒泡,选择,插入和快速排序法PHP基础教程

php四种基础算法:冒泡,选择,插入和快速排序法