归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。
算法原理:
-
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
-
设定两个指针,最初位置分别为两个已经排序序列的起始位置;
-
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
-
重复步骤 3 直到某一指针达到序列尾;
-
将另一序列剩下的所有元素直接复制到合并序列尾。
复杂度分析:
时间复杂度
归并排序算法每次将序列折半分组,共需要logn轮,因此归并排序算法的时间复杂度是O(nlogn)
空间复杂度
归并排序算法排序过程中需要额外的一个序列去存储排序后的结果,所占空间是n,因此空间复杂度为O(n)
稳定性
归并排序算法在排序过程中,相同元素的前后顺序并没有改变,所以归并排序是一种稳定排序算法
代码实现:
void merge(vector<int> & arr, int low, int mid, int high)
{
//创建临时数组存放合并的数组
vector<int> temp(high - low + 1);
int i = low, j = mid + 1, k = 0;
while (i <= mid && j <= high)
temp[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++];
//当一个数组中元素被取完时,直接将另外一个数组的剩余元素添加到临时数组
while (i <= mid)
temp[k++] = arr[i++];
while (j <= high)
temp[k++] = arr[j++];
//将临时数组中的元素存入原始数组对应位置
for (i = low, k = 0; i <= high && k<=high - low + 1; i++, k++)
arr[i] = temp[k];
}
void mergeSort(vector<int> & arr, int low, int high)
{
if (low >= high)
return;
int mid = (low + high) / 2;
//左右子数组分别递归,并调用merge合并
mergeSort(arr, low, mid);
mergeSort(arr, mid + 1, high);
merge(arr, low, mid, high);
}
代码参考:C++归并排序代码_weixin_42383066的博客-CSDN博客_归并排序c++代码
图源出处:1.5 归并排序 | 菜鸟教程