1、归并排序
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
2、递归实现
因为使用了递归算法,所以在数据比较大的情况下,有可能会造成递归的层次太深,算法效率不高,这里加入了一点改进,即在数据量比较小的时候调用插入排序来处理,源码如下所示:
2.1 源码
#include<stdio.h>
#include<iostream>
#include<stack>
using namespace std;
//插入排序
void InsertSort(int array[], size_t size){
for (size_t i = 1; i < size; ++i){
int key = array[i];
int cur = i - 1;
while (cur >= 0 && key < array[cur]){
array[cur + 1] = array[cur];
cur--;
}
array[cur + 1] = key;
}
}
//归并
void MergeData(int arr[], int left, int mid, int right, int* temp){
int begin1 = left;
int end1 = mid;
int begin2 = mid;
int end2 = right;
int index = 0;
while (begin1 < end1 && begin2 < end2){
if (arr[begin1] <= arr[begin2])
temp[index++] = arr[begin1++];
else
temp[index++] = arr[begin2++];
}
while (begin1<end1)
temp[index++] = arr[begin1++];
while (begin2<end2)
temp[index++] = arr[begin2++];
for (int i = 0; i < index; i++)
arr[left + i] = temp[i];
}
// 划分
void _MergeSort(int arr[], int left, int right, int * temp){
if (right - left > 1){
if (right - left < 15)
InsertSort(arr, right - left);
int mid = left + ((right - left) >> 1);
_MergeSort(arr, left, mid, temp);
_MergeSort(arr, mid, right, temp);
MergeData(arr, left, mid, right, temp);
}
}
void MergeSort(int arr[], int size){
int * temp = new int[size];
_MergeSort(arr, 0, size, temp);
delete[] temp;
}
void Print(int arr[], int len){
for (int i = 0; i < len; ++i){
cout << arr[i] << " ";
}
cout << endl;
}
int main(){
int arr[] = { 2, 5, 9, 3, 1, 7, 0, 4, 8, 1, 9, 4, 2, 7, 9, 12, 3, 8, 2, 34, 6, 7, 95, 24, 1, 34, 58, 21, 9, 23, 75, 43, 54, 65, 23, 44, 41, 67, 34, 91, 34, 78, 90, 34, 66, 44, 22, 11, 44, 66, 23, 77, 45, 92, 12, 101 };
int size = sizeof(arr) / sizeof(arr[0]);
cout << "排序前:" << endl;
Print(arr, size);
MergeSort(arr, size);
cout << "递归版归并排序:" << endl;
Print(arr, size);
return 0;
}
2.2 程序运行结果
3、迭代版归并排序
3.1 源码
#include<stdio.h>
#include<iostream>
#include<stack>
using namespace std;
//插入排序
void InsertSort(int array[], size_t size){
for (size_t i = 1; i < size; ++i){
int key = array[i];
int cur = i - 1;
while (cur >= 0 && key < array[cur]){
array[cur + 1] = array[cur];
cur--;
}
array[cur + 1] = key;
}
}
//归并
void MergeData(int arr[], int left, int mid, int right, int* temp){
int begin1 = left;
int end1 = mid;
int begin2 = mid;
int end2 = right;
int index = 0;
while (begin1 < end1 && begin2 < end2){
if (arr[begin1] <= arr[begin2])
temp[index++] = arr[begin1++];
else
temp[index++] = arr[begin2++];
}
while (begin1<end1)
temp[index++] = arr[begin1++];
while (begin2<end2)
temp[index++] = arr[begin2++];
for (int i = 0; i < index; i++)
arr[left + i] = temp[i];
}
int min(int left, int right){
if (left>right)
return right;
else
return left;
}
// 划分
void _MergeSort(int arr[], int left, int right, int * temp){
int len = right - left;
for (int step = 1; step < len; step <<= 1){
int offset = step + step;
for (int index = 0; index < len; index += offset){
MergeData(arr, index, min(index + step, len - 1), min(index + offset, len - 1),temp);
}
}
}
void MergeSort(int arr[], int size){
int * temp = new int[size];
_MergeSort(arr, 0, size, temp);
delete[] temp;
}
void Print(int arr[], int len){
for (int i = 0; i < len; ++i){
cout << arr[i] << " ";
}
cout << endl;
}
int main(){
int arr[] = { 2, 5, 9, 3, 1, 7, 0, 4, 8, 1, 9, 4, 2, 7, 9, 12, 3, 8, 2, 34, 6, 7, 95, 24, 1, 34, 58, 21, 9, 23, 75, 43, 54, 65, 23, 44, 41, 67, 34, 91, 34, 78, 90, 34, 66, 44, 22, 11, 44, 66, 23, 77, 45, 92, 12, 101 };
int size = sizeof(arr) / sizeof(arr[0]);
cout << "排序前:" << endl;
Print(arr, size);
MergeSort(arr, size);
cout << "迭代版归并排序:" << endl;
Print(arr, size);
return 0;
}