快速排序的php實現


  再來一個非常高級的排序算法,快速排序...這個算法是很高效的。

快速排序的思路是,找到一個分割點(中樞點 默認是列表第一個值),把原列表分隔成兩部分,在分割點左側的是都比它小的,在它右側的是都比它大的。然后分別把這兩部分再遞歸調用排序,自然就全部排序完成。

當然最重要的步驟就是切分,然后進行遞歸調用,重復以上分割操作,直到break。代碼示例如下:

第一種實現更能直觀細節展示出快排中的含義:

 

$arr = array(19, 17, 13, 16,12 , 11, 4, 9, 77, 18);

qsort(0, count($arr) - 1, $arr);

echo "<pre>";
print_r($arr);

/**
 * @param $low
 * @param $high
 * @param $arr
 * 快速排序 遞歸調用
 * 關鍵點在於part動作
 */
function qsort($low, $high, &$arr){
    if($low < $high){
        $pivot = part($low, $high, $arr);
        qsort($low, $pivot-1, $arr);
        qsort($pivot+1, $high, $arr);
    }

}


/**
 * @param $low
 * @param $high
 * @param $arr
 * @return mixed
 * part的核心動作在於-- 中樞點的位置不斷變換,比它小的換到它的左邊,比它大的換到它的右邊
 */
function part($low, $high, &$arr){
    $pivot = $arr[$low];// 中樞點默認是列表第一個

    while($low < $high){
        while($low < $high && $arr[$high] >= $pivot){// 右邊選比中樞點小的
            $high--;
        }
        swap($arr, $low, $high);// 此時中樞點在低位置,而此時的高位置小於中樞點。兩點交換

        while($low < $high && $arr[$low] <= $pivot){// 左邊選比中樞點大的
            $low++;
        }
        swap($arr, $low, $high);// 此時中樞點在高位置,而此時的低位置大於中樞點。兩點交換
    }

    return $low;// 低位此時是中樞點,返回中樞點位置
}

/**
 * @param $arr
 * @param $i
 * @param $j
 * 交換位置
 */
function swap(&$arr, $i, $j){
    $temp = $arr[$i];
    $arr[$i] = $arr[$j];
    $arr[$j] = $temp;
}

 

理解快速排序怎么交換值這點尤為關鍵,這個算法很機智。。加深理解算法中的智慧吧~

 

 

另一種流傳比較廣的php寫快速排序,切分后的兩邊用兩個數組裝起來。

代碼:

 

$arr = array(19, 17, 13, 16, 12, 11, 4, 9, 77, 18);

echo "<pre>";
print_r(quick_sort($arr));

/**
 * @param $arr
 * @return array
 * 快速排序
 */
function quick_sort($arr) {
    // 遞歸結束: 數組長度為1,直接返回
    $length = count($arr);
    if ($length <= 1) {
        return $arr;
    }
    // 數組元素有多個,則定義兩個空數組
    $left = $right = array();
    // 使用for循環進行遍歷,默認第一個元素作為中樞點
    for ($i = 1; $i < $length; $i++) {
        // 判斷當前元素的大小
        if ($arr[$i] < $arr[0]) {
            $left[] = $arr[$i];
        } else {
            $right[] = $arr[$i];
        }
    }
    // 遞歸調用
    $left = quick_sort($left);
    $right = quick_sort($right);
    // 將所有的結果合並
    return array_merge($left, array($arr[0]), $right);// 中間切點
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM