归并排序是一种基于分治思想的排序算法,利用递归将数组分割成若干子数组,再将它们合并为有序数组。归并排序稳定且效率较高,适用于大规模数据的排序。


目录

  1. 算法思路
  2. PHP 代码实现
  3. 时间复杂度分析
  4. 适用场景与优势
  5. 练习题
  6. 相关链接
  7. 参考资料

算法思路

归并排序采用分治法将问题分解为若干个小问题。基本步骤如下:

  • 分解:将数组不断二分,直到每个子数组只含一个元素(单个元素视为有序)。
  • 合并:将两个有序子数组合并成一个新的有序数组,逐步向上归并,直至整个数组有序。

这种分而治之的策略保证了排序过程的稳定性,并能在 O(n log n) 的时间复杂度内完成排序。


PHP 代码实现

下面给出归并排序的 PHP 实现示例:

<?php
// 归并排序函数
function mergeSort(array $arr): array {
    $n = count($arr);
    if ($n <= 1) {
        return $arr;
    }
    
    $mid = (int)($n / 2);
    $left = array_slice($arr, 0, $mid);
    $right = array_slice($arr, $mid);
    
    // 分别对左右部分排序
    $left = mergeSort($left);
    $right = mergeSort($right);
    
    // 合并排序好的子数组
    return merge($left, $right);
}

// 合并两个有序数组
function merge(array $left, array $right): array {
    $result = [];
    $i = $j = 0;
    
    while ($i < count($left) && $j < count($right)) {
        if ($left[$i] <= $right[$j]) {
            $result[] = $left[$i];
            $i++;
        } else {
            $result[] = $right[$j];
            $j++;
        }
    }
    
    // 添加剩余元素
    while ($i < count($left)) {
        $result[] = $left[$i++];
    }
    
    while ($j < count($right)) {
        $result[] = $right[$j++];
    }
    
    return $result;
}

// 测试示例
$data = [38, 27, 43, 3, 9, 82, 10];
echo "排序前: " . implode(", ", $data) . "\n";
$sorted = mergeSort($data);
echo "排序后: " . implode(", ", $sorted) . "\n";
?>

输出示例:

排序前: 38, 27, 43, 3, 9, 82, 10
排序后: 3, 9, 10, 27, 38, 43, 82


时间复杂度分析

情况时间复杂度
最佳情况O(n log n)
最坏情况O(n log n)
平均情况O(n log n)

归并排序在所有情况下均保持 O(n log n) 的时间复杂度。此外,归并排序是稳定排序,但由于需要额外的空间来存储合并结果,其空间复杂度为 O(n)。


适用场景与优势

  • 大规模数据排序:归并排序适合于数据量较大且数据随机分布的情况,能保持较高的效率。
  • 稳定性要求高:归并排序在合并过程中不会改变相同元素的相对顺序,因此是一种稳定排序。
  • 外部排序:当数据量过大无法全部载入内存时,归并排序特别适用,比如磁盘归并排序。
  • 并行化优势:由于归并排序采用分治思想,各个子问题可以并行处理,有利于分布式计算环境下的优化。

练习题

  1. 递归实现与非递归实现:分别用递归和非递归方式实现归并排序,并对比两种方法的性能和代码复杂度。
  2. 空间优化:尝试在归并排序中原地排序,减少额外空间的使用,讨论其可行性和实现难度。
  3. 归并排序与其他排序算法比较:在相同数据集上实现归并排序、快速排序和堆排序,比较它们在最佳、最坏和平均情况的性能差异。
  4. 扩展练习:将归并排序应用于链表排序,实现对链表的归并排序算法,并分析时间和空间复杂度。

相关链接

🔗 GeeksforGeeks – Merge Sort
🔗 Algorithm Visualizer – Merge Sort
🔗 Wikipedia – Merge Sort


参考资料

  1. 《算法导论》—— Thomas H. Cormen 等
  2. 《数据结构与算法分析》—— Mark Allen Weiss
  3. GeeksforGeeks – Sorting Algorithms

归并排序凭借其稳定性和一致的 O(n log n) 时间复杂度,成为处理大规模数据排序的经典算法。通过理解分治思想和归并过程,你可以更高效地实现排序,并在实践中不断优化和改进。Happy Coding! 🚀