#include<time.h>
#include<iostream>
#include<string.h>
using namespace std;
void show(int a[], int length) {
for (int i = 1; i <= length; i++) {
if (a[i] != 0)
cout << a[i] << " ";
}
cout << endl;
}
/*整体思想:
假设初始序列有N个记录,则可以看成是n个有序的子序列,每个子序列是1个长度,然后两两相互合……,如此往复得到一个N的序列
*/
//算法第一步:相邻2个有序子序列的归并
/*
设2个有序表存放在同一数组中相邻的位置上:R[low...mid]和R[mid+1...high],每次从2个表中取出一个记录进行关键字的比较,将最小的放入T[]中,
重复,知道其中一个的表位空,然后把剩下的部分直接赋值到T中
*/
int changeTime = 0, compareTime = 0;
void Merge(int R[], int T[], int low, int mid, int high) {//每次归并,需要调用至多n/2*h次算法,(h为每个子序列长度)
int i = low, j = mid + 1, k = low;
//表的2半段都非空
while (i <= mid && j <= high) {
if (R[i] <= R[j]) {
T[k++] = R[i++];
}
else
T[k++] = R[j++];
changeTime++;
compareTime++;
}
while (i <= mid) { T[k++] = R[i++]; changeTime++; }//左边还存在值
while (j <= high) { T[k++] = R[j++]; changeTime++; }//右边存在值
}
//归并排序调用递归
/*
(1)将当前序列一分为二,找出分裂点
(2)对于左子序列递归归并排序,放入S[low,mid]中
(3)对于子序列R[mid+1,high]递归,进行归并排序,放入S[mid+1,high]中
(4)调用Merge函数把S都前面和后面归并成一个有序的序列
*/
void MSort(int R[], int T[], int low, int high) {
int S[17] = { 0 };
if (low == high) T[low] = R[high];
else {
int mid = (low + high) / 2;//对当前的序列一分为二,求分裂点
MSort(R, S, low, mid);//对low-mid递归排序
MSort(R, S, mid + 1, high);//对mid+1 ->high递归排序
Merge(S, T, low, mid, high);//将排好序归并到T中
show(T, 16);
}
}
//算法分析
/*
(1)时间复杂度 O(n*log2n)
(2)空间复杂度 O(N)需要辅助数组
特点:稳定排序
可以用于链式结构,递归实现时需要开辟相应的递归工作栈
*/
int main() {
int *a = new int[17];
int *b = new int[17];
int length = 16;
srand(unsigned(time(0)));
memset(a, 0, sizeof(a));
for (int i = 1; i <= 16; i++) {
a[i] = rand() % 90 + 10;
}
cout << "==============" << endl;
cout << "归并排序:" << endl;
cout << "==============" << endl;
cout << "before sort:" << ends;
for (int i = 1; i <= 16; i++) {
cout << a[i] << " ";
}
cout << endl;
MSort(a, b, 1, 16);
cout << "after sort:" << ends;
for (int i = 1; i <= 16; i++) {
cout << b[i] << " ";
}
cout << endl;
cout << "changTime=" << changeTime << ",compareTime=" << compareTime << endl;
delete a;
a = NULL;
delete b;
b = NULL;
}