05-归并排序

1 基本思想

归并排序算法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,使每个子序列有序,再将已有序的子序列合并,得到完全有序的序列。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

2 算法过程

1、“分解”——将序列每次折半划分。 2、“合并”——将划分后的序列段两两合并后排序。

3 算法图解

算法图解

4 PHP代码实现

/**
 * 归并排序: 对半拆分元素, 拆到底后, 比较左右两边元素, 让其有序后, 回归
 * 时间复杂度: O(nlogn)
 * 空间复杂度: O(n)
 * 稳定排序(相等元素的顺序不会改变)
 */

function mergeSort(&$arr, $start, $end) {
    if ($start < $end) {
        $mid = floor(($start + $end) / 2);
        mergeSort($arr, $start, $mid);
        mergeSort($arr, $mid + 1, $end);
        merge($arr, $start, $mid, $end);
    }
}

function merge(&$arr, $start, $mid, $end) {
    $i = $start;
    $j = $mid + 1;
    $temp = [];
    while( $i <= $mid && $j <= $end) {
        if($arr[$i] < $arr[$j]) {
            $temp[] = $arr[$i];
            ++$i;
        } else {
            $temp[] = $arr[$j];
            ++$j;
        }
    }

    while($i <= $mid) {
        $temp[] = $arr[$i];
        ++$i;
    }

    while($j <= $end) {
        $temp[] = $arr[$j];
        ++$j;
    }

    for ($k = 0; $k < count($temp); ++$k) {
        $arr[$k + $start] = $temp[$k];
    }
}

$arr = [38, 19, 29, 91, 85, 12, 41, 21];
mergeSort($arr, 0, count($arr) - 1);
print_r($arr);

5 效率分析

1、时间复杂度:O(nlogn) 最好情况、最坏情况和平均时间复杂度均为O(nlogn); 2、空间复杂度:O(n) 算法处理过程中,需要一个大小为 n 的临时存储空间保存合并序列,所以空间复杂度为O(n)。 3、稳定性:稳定 在归并排序中,相等的元素的顺序不会改变,所以它是稳定排序。


Last modified March 8, 2022: Fix image path (67fc7f5)