Introduction
Merge sort is a sorting algorithm with time complexity of O (n log n) level, and is a stable sorting algorithm. Because each part it divides is the same size in space. The following uses C ++ to implement a basic merge sort algorithm, and optimize and improve it.
Specific ideas
- Divide the array arr [l… r] that needs to be sorted into two, and set an intermediate position index mid until each group of elements has only one element.
- Open up a temporary array temp [0… rl] and copy the array arr [l ... r] that needs to be sorted.
- Compare the first element of temp [0 ... mid-l] and temp [mid-l + 1 ... rl] respectively, and meet the sorting requirement to cover arr until all elements in temp are overwritten to the arr array.
Code
#include<bits/stdc++.h>
using namespace std;
template<class T>
void _merge(T arr[], int l, int mid, int r) {
//开辟一个临时数组用于存放归并后的元素
T* temp = new T[r-l+1];
for(int i = l; i <= r; i++) {
temp[i-l] = arr[i];
}
int i = l;
int j = mid+1;
for(int k = l; k <= r; k++) {
//当左边元素都已排好
if(i > mid) {
arr[k] = temp[j-l];
j++;
}
//当右边元素都排好
else if(j > r) {
arr[k] = temp[i-l];
i++;
}
//左边元素较小时
else if(temp[i-l] < temp[j-l]) {
arr[k] = temp[i-l];
i++;
}
else {
arr[k] = temp[j-l];
j++;
}
}
return;
}
//对arr[l...r]排序
template<class T>
void _mergeSort(T arr[], int l, int r) {
//退出条件
if(l >= r) {
return;
}
//将数组元素一分为二
int mid = l + (r-l)/2;
//分别对左右部分归类
_mergeSort(arr, l, mid);
_mergeSort(arr, mid+1, r);
//之后合并
//如果右边第一个元素比左边最后一个元素大就不需要归并了
if(arr[mid] > arr[mid+1])
_merge(arr, l, mid, r);
}
template<class T>
void mergeSort(T arr[], int n) {
//对数组arr[0...n-1]排序
_mergeSort(arr, 0, n-1);
}
int main(int argc, char const *argv[])
{
//测试
int arr[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
mergeSort(arr, 10);
for(int i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
return 0;
}
Bottom-up merge sort
#include<bits/stdc++.h>
using namespace std;
template<class T>
void _merge(T arr[], int l, int mid, int r) {
//开辟一个临时数组用于存放归并后的元素
T* temp = new T[r-l+1];
for(int i = l; i <= r; i++) {
temp[i-l] = arr[i];
}
int i = l;
int j = mid+1;
for(int k = l; k <= r; k++) {
//当左边元素都已排好
if(i > mid) {
arr[k] = temp[j-l];
j++;
}
//当右边元素都排好
else if(j > r) {
arr[k] = temp[i-l];
i++;
}
//左边元素较小时
else if(temp[i-l] < temp[j-l]) {
arr[k] = temp[i-l];
i++;
}
else {
arr[k] = temp[j-l];
j++;
}
}
return;
}
//自底向上的归并排序
template<class T>
void mergeSortBtoU(T arr[], int n) {
//l = i, mid = sz - 1, r = i + sz + sz - 1
for(int sz = 1; sz < n; sz += sz) {
for(int i = 0; i + sz < n; i += sz + sz) {
if(arr[i+sz-1] > arr[i+sz]) {
_merge(arr, i, i+sz-1, min(i+sz+sz-1, n-1));
}
}
}
}
int main(int argc, char const *argv[])
{
// 测试
int arr[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
mergeSortBtoU(arr, 10);
for(int i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
return 0;
}
At last
- Due to the limited level of bloggers, there are inevitable omissions, readers are welcome to criticize and correct!