介绍
归并排序算法实质上是采用“分治”的思想来解决问题的。
思想
先将序列元素分解成单个元素,然后再两两比较形成有序序列。针对合合并后的有序序列,再次进行两两比较,直到生成一个有序序列为止。如图:
排序步骤
- 首先创建一个与原有序列空间一样大的序列空间,并用该空间来存放合并后的序列。
- 根据序列的起始和结束位置确定该序列的中间点,利用递归的形式分解序列,形成单独的元素。
- 设置两个指针,分别指向相邻两个序列的起始位置,比较两个指针指向的元素选择较小 / 较大的放入合并空间中,并移动已经放入合并空间的指针到下移位置,直到所有元素都是有序系列为止。
其中最后两个有序序列合并过程也被称为二路归并排序。通过归并排序的算法描述可知,该算法需要另辟空间来存储排序序列,所以其辅助空间均为 O ( n ) O(n) O(n) ,时间复杂度与快速排序算法相似,都是 O ( n log n ) O(n\log n) O(nlogn) 在稳定性方面为稳定的排序算法。因此,当该排序数据量较大,且这些数据本身是有序的,对稳定性也有要求,且对于空间没有特殊要求时,可以采用该方法。
代码
C++版
#include <iostream>
using namespace std;
void merge(int arr[], int left, int mid, int right) {
int i, j, k;
int n1 = mid - left + 1;
int n2 = right - mid;
int L[n1], R[n2];
for (i = 0; i < n1; i++)
L[i] = arr[left + i];
for (j = 0; j < n2; j++)
R[j] = arr[mid + 1 + j];
i = 0;
j = 0;
k = left;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
void merge_sort(int arr[], int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
merge_sort(arr, left, mid);
merge_sort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
}
int main() {
int arr[] = {9, 5, 2, 7, 1, 8, 3};
int size = sizeof(arr) / sizeof(arr[0]);
merge_sort(arr, 0, size - 1);
for (int i = 0; i < size; i++)
cout << arr[i] << " ";
return 0;
}
这段代码定义了两个函数:merge
和merge_sort
。merge
函数用于合并两个已排序的子数组,merge_sort
函数用于将数组分成子数组并递归地对其进行排序。
在merge
函数中,我们首先计算两个子数组的长度,然后创建临时数组L
和R
来存储这两个子数组的元素。接着,我们使用双指针来比较并合并两个子数组的元素,将结果存储到原始数组arr
中。
在merge_sort
函数中,我们首先判断数组的左右边界,如果左边界小于右边界,则计算中间位置,并递归调用merge_sort
函数来对左右两个子数组进行排序。最后,我们调用merge
函数将两个有序子数组合并起来。
在main
函数中,我们定义了一个数组arr
,然后调用merge_sort
函数对其进行排序,并打印出排序后的结果。
Python版
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left_half = arr[:mid]
right_half = arr[mid:]
left_half = merge_sort(left_half)
right_half = merge_sort(right_half)
return merge(left_half, right_half)
def merge(left_half, right_half):
merged = []
left_index = 0
right_index = 0
while left_index < len(left_half) and right_index < len(right_half):
if left_half[left_index] < right_half[right_index]:
merged.append(left_half[left_index])
left_index += 1
else:
merged.append(right_half[right_index])
right_index += 1
merged += left_half[left_index:]
merged += right_half[right_index:]
return merged
# 测试
arr = [4, 2, 5, 1, 3]
sorted_arr = merge_sort(arr)
print(sorted_arr)
总结
归并排序是辅助空间均为 O ( n ) O(n) O(n) ,时间复杂度为 O ( n log n ) O(n\log n) O(nlogn) 在稳定性方面为稳定的排序算法。如果对你有帮助,那就点个赞吧!球球辣
顺便点个关注, 给作者增加点储备粮吧pwp