Laravel之冒泡、快速、選擇和插入排序(持續更新)

說明:本文是對我的學習冒泡、快速、選擇和插入排序的小總結。面試常常問這些東西,雖然不知道爲啥老愛問這些,該問的又不問。無論咋樣,我的學習MySQL時有關索引就用到快速排序,索引也是以B+Tree數據結構保存的(Innodb存儲引擎),因此基本功仍是很重要的嘛。php

快速排序

我的實驗發現,快速排序在這四個排序當中彷佛是最快的,看下圖比較直觀:面試

看下代碼吧:算法

<?php
/** * Created by PhpStorm. * User: liuxiang * Date: 16/6/15 * Time: 21:33 */

class QuickSort{
    
    /** * 遞歸 * * 快速排序過程: * 1.給初始值,$mid=$data[0] * 2.第二個值開始,與$mid比較,小的放在左邊,大的放在右邊 * 3.遞歸,直到數組就剩一個值 * * 效率低,還使用了array_merge()方法 * * @param array $data * @return array */
    public function arrayQuickSort(array $data)
    {
        $count = count($data);
        if($count <= 1){
            return $data;
        }
        $mid   = $data[0];
        $left  = $right = [];
        for($i=1; $i<$count; $i++){
            ($data[$i] < $mid) ? $left[] = $data[$i] :$right[]=$data[$i];
        }
        $left  = $this->arrayQuickSort($left);
        $right = $this->arrayQuickSort($right);

        return array_merge($left, [$mid], $right);
    }

}

$arr       = [5, 4, 5, 3, 8, 10, 3, 2, 4, 7];
$arr2      = array_rand(range(1, 1000), 500);
shuffle($arr2);

$quickSort = new QuickSort();

$time1     = microtime(true);
//$quickArr = $quickSort->arrayQuickSort($arr);
$quickArr  = $quickSort->arrayQuickSort($arr2);//11.8780136108ms
$time2     = microtime(true);

//var_dump($quickArr);
echo (($time2 - $time1)*1000).'ms'.PHP_EOL;

實驗快速排序,排序隨機的500個數只要11ms左右,還挺快。數組

冒泡排序

冒泡排序效率就比較差了,看圖比較直觀它的原理:數據結構

看代碼吧:學習

<?php
/** * Created by PhpStorm. * User: liuxiang * Date: 16/6/15 * Time: 21:26 */
class BubbleSort{
    /** * 非遞歸 * * 冒泡排序算法過程: * 1.比較相連兩個元素,若是第一個比第二個大,交換位置 * 2.n個數,須要觀察n-1次 * 3.每個數number,須要與其他n-1個數比較,但實際只須要排序n-1-$i,如5,4,3,2,1就5通過4=5-1-0次排序4,3,2,1,5,而4只通過3=5-1-1次排序3,2,1,4,5 * 4.直到排序次數走完,一個亂序就可排爲升序或降序了 * 平均時間複雜度最優n,最差n^2 */
    /** * @param array $data * @return array */
    public function arrayBubbleSort(array $data){
        $count = count($data);
        for($i=0; $i<$count; $i++){
            for($j=0; $j<$count-1-$i; $j++){
// for($j=0; $j<$count-1; $j++){//這樣也能夠,不過多了$i次比較
                if($data[$j] > $data[$j+1]){
                    $this->swap($data[$j], $data[$j+1]);
                }
            }
        }

        return $data;
    }

    /** * 字符串排序也和數組同樣,字符串數組形式訪問字符 * @param string|string $str * @return string */
    public function stringBubbleSort(string $str)
    {
        $count = strlen($str);
        for($i=0; $i<$count; $i++){
            for($j=0; $j<$count-1-$i; $j++){
                if($str[$j] > $str[$j+1]){
                    $this->swap($str[$j], $str[$j+1]);
                }
            }
        }

        return $str;
    }

    /** * 交換變量值 * @param $var1 * @param $var2 */
    public function swap(&$var1, &$var2)
    {
        $tmp  = $var1;
        $var1 = $var2;
        $var2 = $tmp;
    }
}

$arr   = [5, 4, 5, 3, 8, 10, 3, 2, 4, 7];
$str   = 'SegmentFault';
$arr2  = array_rand(range(1, 1000), 500);
shuffle($arr2);

$sort  = new BubbleSort();

$time1 = microtime(true);
//$bubbleArr = $sort->arrayBubbleSort($arr);
$bubbleArr = $sort->arrayBubbleSort($arr2);//316.018104553ms
$time2 = microtime(true);

//var_dump($bubbleArr);
echo (($time2 - $time1)*1000).'ms'.PHP_EOL;

實驗冒泡排序,排序隨機的500個數須要316ms左右,慢的不行。ui

插入排序

插入排序我的以爲就像是玩撲克,牌桌上n張牌,一張張抓過來,而後新牌根據手上的m張牌依次比較,找到對應位置。看圖比較直觀:this

看代碼吧:spa

<?php

/** * Created by PhpStorm. * User: liuxiang * Date: 16/6/23 * Time: 18:14 */
class InsertSort
{
    /** * 插入排序具體算法描述 * 1.從第一個元素開始,該元素能夠認爲已經被排序 * 2.取出下一個元素,在已經排序的元素序列中從後向前掃描 * 3.若是該元素(已排序)大於新元素,將該元素移到下一位置 * 4.重複步驟3,直到找到已排序的元素小於或者等於新元素的位置 * 5.將新元素插入到該位置後 * 6.重複步驟2~5 * * @param array $data * @return array */
    public function arrayInsertSort(array $data)
    {
        $count = count($data);
        for($i=0; $i<$count-1; $i++){
            for($j=$i+1; $j>0; $j--){
                if($data[$j] > $data[$j-1]){
                    break;
                }
                $this->swap($data[$j-1], $data[$j]);
            }
        }

        return $data;
    }

    /** * 交換變量值 * @param $var1 * @param $var2 */
    public function swap(&$var1, &$var2)
    {
        $tmp  = $var1;
        $var1 = $var2;
        $var2 = $tmp;
    }

}

$arr       = [5, 4, 5, 3, 8, 10, 3, 2, 4, 7];
$arr2      = array_rand(range(1, 1000), 500);
shuffle($arr2);
$insert    = new InsertSort();

$time1     = microtime(true);
//$insertArr = $insert->arrayInsertSort($arr);
$insertArr = $insert->arrayInsertSort($arr2);//315.321922302ms
$time2     = microtime(true);

//var_dump($insertArr);
echo (($time2 - $time1)*1000).'ms'.PHP_EOL;

實驗插入排序,排序隨機的500個數須要315ms左右,和冒泡排序差很少速度。3d

選擇排序

選擇排序速度還行,看圖:

看代碼吧:

<?php

/** * Created by PhpStorm. * User: liuxiang * Date: 16/6/23 * Time: 17:50 */
class SelectSort
{
    /** * 1.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置 * 2.再從剩餘未排序元素中繼續尋找最小(大)元素,放到已排序序列的末尾 * 3.以此類推,直到全部元素均排序完畢 * * @param array $data * @return array */
    public function arraySelectSort(array $data)
    {
        $count = count($data);
        for($i=0; $i<$count - 1; $i++){
            $min = $i;
            for($j=$i+1; $j<$count; $j++){
                if($data[$min] > $data[$j]){
                    $min = $j;
                }
            }
            
            if($min != $i){
                $this->swap($data[$min], $data[$i]);
            }
        }

        return $data;
    }

    /** * 交換變量值 * @param $var1 * @param $var2 */
    public function swap(&$var1, &$var2)
    {
        $tmp  = $var1;
        $var1 = $var2;
        $var2 = $tmp;
    }

}

$arr2      = array_rand(range(1, 1000), 500);
shuffle($arr2);
$arr       = [5, 4, 5, 3, 8, 10, 3, 2, 4, 7];

$select    = new SelectSort();

$time1     = microtime(true);
//$selectArr = $select->arraySelectSort($arr);
$selectArr = $select->arraySelectSort($arr2);//44.0230369568ms
$time2 = microtime(true);

//var_dump($selectArr);
echo (($time2 - $time1)*1000).'ms'.PHP_EOL;

實驗選擇排序,排序隨機的500個數須要44ms左右,速度還行。

總結:排序和查找是永恆主題。紮實下基本功,會繼續學習相關排序和查找算法,到時見。

相關文章
相關標籤/搜索