排序 - 归并排序

来源:互联网 发布:李小璐遇网络诈骗 编辑:程序博客网 时间:2024/06/05 17:31

归并:将两个或两个以上的有序序列合并成一个新的有序序列,这种归并方法称为2路归并;

将3个有序序列归并为一个新的有序序列,称为3路归并;

将多个有序序列归并为一个新的有序序列,称为多路归并。


合并过程:

1、设置i,j 和 p 三个指针,其初值分别指向这三个记录区的起始位置;

2、合并时依次比较R[i]和R[j]的关键字,取关键字较小的记录复制到R1[p]中;

3、然后将被复制记录的指针 i 或 j 加1,以及指向复制位置的指针 p 加1;

4、重复这一过程直至两个输入的子文件有一个已全部复制完毕(不妨称其为空),此时将另一非空的子文件中剩余记录一次复制到R1中即可。

时间复杂度O(nlogn)。


代码:

#include <iostream>#include <cstdio>#include <ctime>#include <iomanip>using namespace std;int arr[10000];inline void mySwap(int &a, int &b){int t = a;a = b;b = t;}void merge(int A[], int tmpA[], int leftPos, int rightPos, int rightEnd){int leftEnd = rightPos - 1;int tmpPos = leftPos;int num = rightEnd - leftPos + 1;// 从大到小放到临时矩阵中while (leftPos <= leftEnd && rightPos <= rightEnd) {if (A[leftPos] <= A[rightPos]) {tmpA[tmpPos++] = A[leftPos++];}else {tmpA[tmpPos++] = A[rightPos++];}}// 剩下的while (leftPos <= leftEnd) {tmpA[tmpPos++] = A[leftPos++];}while (rightPos <= rightEnd) {tmpA[tmpPos++] = A[rightPos++];}for (int i = 0; i < num; i++, rightEnd--) {A[rightEnd] = tmpA[rightEnd];}}void MSort(int A[], int tmpA[], int L, int R){int mid;if (L < R) {mid = (L + R) / 2;MSort(A, tmpA, L, mid);MSort(A, tmpA, mid + 1, R);merge(A, tmpA, L, mid + 1, R);}}void mergeSort(int A[], int len){int *tmpA = new int[len];if (tmpA != NULL) {MSort(A, tmpA, 0, len - 1);delete [] tmpA;}else {cout << "No space for tmp array!!!\n";}}void printArray(int *a, int len){for (int i = 0; i < len; i++) {if (i != 0 && i % 10 == 0) {cout << endl;}cout << setw(3) << a[i] << ' ';}cout << endl;}int main(){srand(time(0));cout << "Please input length of array: ";int len;cin >> len;for (int i = 0; i < len; i++) {arr[i] = rand() % 100;}cout << "Before sorting:\n";printArray(arr, len);mergeSort(arr, len);cout << "After sorting:\n";printArray(arr, len);return 0;}/*Please input length of array: 20Before sorting:55  89  51  31  24  86  41  82  83  5836  41  84  88  99   1  38  96  31  27After sorting: 1  24  27  31  31  36  38  41  41  5155  58  82  83  84  86  88  89  96  99*/

虽然归并排序的运行时间是O(nlogn),但是它很难用于主存排序,主要问题在于合并两个排序的表需要线性附加内存,在整个算法中还需要花费将数据拷贝靠临时数组再拷贝回来这样一些附加的工作,其结果严重放慢了排序的速度。对于重要的内部排序应用而言,人们还是选择快速排序。而合并是大多少外部排序算法的基石。

0 0
原创粉丝点击