主题
归并排序(Merge Sort)
归并排序是一种经典的 分治算法,通过将大问题递归拆分为小问题分别解决,最后再合并结果完成整体排序。它具备稳定性高、时间复杂度恒定为 O(n log n) 的特点,适用于对稳定性要求较高的场景。
📌 算法原理解释
归并排序采用 “分而治之” 的思想:
- 将数组不断二分(直到只剩一个元素为止);
- 从底向上合并两个有序数组;
- 在合并过程中进行排序。
例如 [5, 3, 8, 4]
会先分为 [5, 3]
和 [8, 4]
,再分为 [5] [3] [8] [4]
,然后合并为 [3, 5] [4, 8]
,最终合并为 [3, 4, 5, 8]
。
优点:性能稳定,适合大规模数据。
缺点:额外的 O(n) 空间复杂度。
💻 多语言代码实现
javascript
// JavaScript 归并排序
function mergeSort(arr) {
if (arr.length <= 1) return arr;
const mid = Math.floor(arr.length / 2);
const left = mergeSort(arr.slice(0, mid));
const right = mergeSort(arr.slice(mid));
return merge(left, right);
}
function merge(left, right) {
const result = [];
let i = 0, j = 0;
while (i < left.length && j < right.length) {
result.push(left[i] <= right[j] ? left[i++] : right[j++]);
}
return result.concat(left.slice(i)).concat(right.slice(j));
}
python
# Python 归并排序
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(left, right):
result = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result += left[i:]
result += right[j:]
return result
cpp
// C++ 归并排序
#include <vector>
using namespace std;
void merge(vector<int>& arr, int left, int mid, int right) {
vector<int> temp;
int i = left, j = mid + 1;
while(i <= mid && j <= right) {
if(arr[i] <= arr[j]) temp.push_back(arr[i++]);
else temp.push_back(arr[j++]);
}
while(i <= mid) temp.push_back(arr[i++]);
while(j <= right) temp.push_back(arr[j++]);
for(int k = 0; k < temp.size(); ++k) {
arr[left + k] = temp[k];
}
}
void mergeSort(vector<int>& arr, int left, int right) {
if(left >= right) return;
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
java
// Java 归并排序
public class MergeSort {
public static void mergeSort(int[] arr, int left, int right) {
if (left >= right) return;
int mid = (left + right) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
private static void merge(int[] arr, int l, int m, int r) {
int[] temp = new int[r - l + 1];
int i = l, j = m + 1, k = 0;
while (i <= m && j <= r) {
temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];
}
while (i <= m) temp[k++] = arr[i++];
while (j <= r) temp[k++] = arr[j++];
System.arraycopy(temp, 0, arr, l, temp.length);
}
}
php
<?php
// PHP 归并排序
function mergeSort(array $arr): array {
if (count($arr) <= 1) return $arr;
$mid = intdiv(count($arr), 2);
$left = mergeSort(array_slice($arr, 0, $mid));
$right = mergeSort(array_slice($arr, $mid));
return merge($left, $right);
}
function merge(array $left, array $right): array {
$result = [];
while (count($left) && count($right)) {
$result[] = $left[0] <= $right[0] ? array_shift($left) : array_shift($right);
}
return array_merge($result, $left, $right);
}
?>
go
// Go 归并排序
package main
func mergeSort(arr []int) []int {
if len(arr) <= 1 {
return arr
}
mid := len(arr) / 2
left := mergeSort(arr[:mid])
right := mergeSort(arr[mid:])
return merge(left, right)
}
func merge(left, right []int) []int {
result := make([]int, 0, len(left)+len(right))
i, j := 0, 0
for i < len(left) && j < len(right) {
if left[i] <= right[j] {
result = append(result, left[i])
i++
} else {
result = append(result, right[j])
j++
}
}
result = append(result, left[i:]...)
result = append(result, right[j:]...)
return result
}
✅ 算法特点与总结
属性 | 描述 |
---|---|
时间复杂度 | O(n log n) |
空间复杂度 | O(n)(需要辅助数组) |
稳定性 | ✅ 稳定 |
是否原地排序 | ❌ 否(使用额外空间) |
📌 提示:归并排序适合处理链表、**外部排序(如大文件排序)**等需要稳定性的应用场景。