归并排序采用分治法
各层的分治可以同时进行
主要步骤:
- 分割 ,递归把当前的序列平均分成两半
- 集合,保证元素顺序的同时,将上一步得到的子序列子集成到一起
下列使用的是递归法,若是想使用迭代法,则自己Google
- 申请空间,用于存放合并(两个已经排好序)的序列。
- 两个指针,分别设为(两个已经排好序)的开始位置。
- 比较两个指针指向的元素,比较大小,小的放到合并空间,指向小的元素指针移向下一个元素,大的不移动
- 重复第3步骤,直到某一个指针到达最后的元素。
- 将另一个剩下的序列元素,直接复制到合并的空间的尾巴。
时间复杂度 为 O (n log n) , 最坏空间复杂度 O (n)
python 代码实现
# 归并排序
def merge(left: list, right: list):
# 申请空间,用于存放合并(两个已经排好序)的序列。
l = []
# 循环,直到某一指针到达序列尾
while len(left) > 0 and len(right) > 0:
# 比较两个指针指向的元素,比较大小,小的放到合并空间,指向小的元素指针移向下一个元素,大的不移动
if left[0] < right[0]:
l.append(left[0])
left.remove(left[0])
else:
l.append(right[0])
right.remove(right[0])
# 将另一个剩下的序列元素,直接复制到合并的空间的尾巴
if len(left) == 0:
l += right
else:
l += left
return l
# 递归拆分
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)
C/C++ 代码实现
#include <iostream>
using namespace std;
void merge(int arr[], int result[], int left, int right)
{
if(left >= right)
return;
int len = right - left;
int mid = len / 2 + left;
int left1 = left;
int right1 = mid;
int left2 = mid + 1;
int right2 = right;
merge(arr, result, left1, right1);
merge(arr, result, left2, right2);
int re = left;
while(left1 <= right1 && left2 <= right2)
{
if(arr[left1] > arr[left2])
{
result[re++] = arr[left2++];
}
else
{
result[re++] = arr[left1++];
}
}
while(left1 <= right1)
{
result[re++] = arr[left1++];
}
while(left2 <= right2)
{
result[re++] = arr[left2++];
}
for(int i = 0; i < re; i++)
{
arr[i] = result[i];
}
}
void mergeSort(int arr[], int arrLen)
{
int result[arrLen];
merge(arr, result, 0, arrLen - 1);
}
int main()
{
int arr[] = {1, 9, 3, 7, 2, 1, 0};
int len = (int) sizeof(arr) / sizeof(*arr);
mergeSort(arr, len);
for(int i = 0; i < len; i++)
{
cout << arr[i] << ' ';
}
cout << endl;
return 0;
}