常用排序算法之归并排序(c++实现)
算法思想
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而**治(conquer)**的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
归并算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。归并排序思路简单,速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。
算法步骤
归并排序是用分治思想,可以递归求解,分治模式在每一层递归上有三个步骤:
- 分解(Divide):将n个元素分成个含n/2个元素的子序列。
- 解决(Conquer):用归并排序法对两个子序列分别排序(递归)。
- 合并(Combine):将两个已排好序的子序列进行归并。
完整c++代码
(1)判断待排序数组是否只剩一个元素,若是则返回;若不是则将数组一分为二;
(2)将分好的两个子序列分别进行归并排序;
(3)将两个已经排好序的子序列进行有序合并。
#include <iostream>
#include <vector>
using namespace std;
void display(vector<int> &array, int size) {
for (int i = 0; i < size; i++) {在这里插入代码片
cout << array[i] << " ";
}
cout << endl;
}
//归并排序
void merge_sort(vector<int> &nums, int l, int r, vector<int> &temp){
if (l == r) return;
int m = l + (r - l) / 2;//将待排序数组分为左右两个子序列`在这里插入代码片`
merge_sort(nums, l, m, temp);//对左边的子序列进行归并排序
merge_sort(nums, m+1, r, temp);//对右边的子序列进行归并排序
int q = l, p = m + 1, i = l;
while (q <= m || p <= r){//对左右两个已排好序的子序列进行有序合并
if (q > m || (p <= r && nums[p] < nums[q])){
temp[i++] = nums[p++];
}
else{
temp[i++] = nums[q++];
}
}
for (i = l; i <= r; i++){
nums[i] = temp[i];
}
}
int main() {
int size = 10;
vector<int> array = { 5, 6, 7, 8, 9,0, 1, 2, 3, 4}; // 数组初始化
vector<int> temp(10, 0);
cout << "原来的数组" << endl;
display(array, size);
merge_sort(array, 0, size - 1, temp);
cout << "排序后的数组" << endl;
display(array, size);
system("pause");
return 0;
}
算法分析
平均时间复杂度:O(nlogn)
最佳时间复杂度:O(n)
最差时间复杂度:O(nlogn)
空间复杂度:O(n)
稳定性:稳定
不管待排序数组有序还是无序都要做这些步骤,所以花销的时间是不变的,所以该算法的最优时间复杂度和最差时间复杂度及平均时间复杂度都为:O( nlogn )。
归并的空间复杂度就是那个临时的数组和递归时压入栈的数据占用的空间:n + logn;所以空间复杂度为: O(n)。
归并排序算法中,归并最后到底都是相邻元素之间的比较交换,并不会发生相同元素的相对位置发生变化,故是稳定性算法。