接下来是代码的实现:
/*
* 归并排序基本思想:
* 设数组Array[]中存放了 N个元素,初始时可以把它们看成长度为 1的N个
* 有序数组。然后,把相邻的有序字数组两两合并,得到[N/2] + 1个长度为 2 的新
* 的有序子数组。再进行两两合并,如此重复,直到得到一个长度为N的有序数组为
* 止。
* 接下来的代码中命名的解释:
* lowerOfFirGroup 第一有序子数组的下界
* upperOfFirGroup 第一有序子数组的上界
* lowerOfSecGroup 第二有序子数组的下界
* upperOfSecGroup 第二有序子数组的上界
* mergedLength 归并的长度
* lengthOfArray 数组的长度
*
*/
#include <iostream>
#include <iomanip>
using namespace std;
#define Size 20
typedef int MergeredLength;
typedef int DataType;
void PaintMergedSort(DataType Array[], int lengthOfArray);
void MergeredSort(DataType Array[], int lengthOfArray);
void Merge(DataType Array[], int lengthOfArray, DataType* Swap, int mergeredLength);
int main(void)
{
DataType Array[Size] = {
12, 34, 45, 56, 98,
65, 43, 32, 21, 65,
87, 76, 76, 43, 32,
83, 62, 6, 89, 77};
PaintMergedSort(Array, Size);
MergeredSort(Array, Size);
PaintMergedSort(Array, Size);
return 0;
}
//输出打印
void PaintMergedSort(DataType Array[], int lengthOfArray)
{
for(int i = 0; i < lengthOfArray; i++)
cout<<Array[i]<<" ";
cout<<endl;
}
//归并排序
void MergeredSort(DataType Array[], int lengthOfArray)
{
MergeredLength mergeredLength = 1; //初始化归并长度为 1;
//初始时可以把它们看成长度为 1 的N个字数组
DataType* Swap;
Swap = new int[lengthOfArray]; //动态申请相同大小的数组空间
while( mergeredLength < lengthOfArray)
{
Merge(Array, lengthOfArray, Swap, mergeredLength);
for(int i = 0; i < lengthOfArray; i++)
Array[i] = Swap[i];
mergeredLength *= 2;
}
delete []Swap;
}
void Merge(DataType Array[], int lengthOfArray, DataType* Swap, int mergeredLength)
{
int lowerOfFirGroup = 0;//每一次都是从第一有序子数组开始,因此第一有序子数组下界都是为 0
int upperOfFirGroup; // 第一有序子数组上界
int lowerOfSecGroup; //第二有序子数组下界
int upperOfSecGroup; // 第二有序子数字上界
int count = 0;//计数
/*
* 一次归并排序算法把长度为"k"的相邻有序子数组从前,后进行两两合并,得到
* 长度为"2k"的有序子数组。
* 出现两个现象:
* (1):若数组元素的个数为"2k"的整数倍,那么两两归并正好完成n个数据元
* 素的一次归并。
* (2):若元素的个数不是2k的整数倍,那么处理方法是:
* A: 若剩余元素的个数 大于 k 而小于 2k, 这把前k个元素作为一个子
* 数组,把剩余的元素作为最后一个子数组。
* B: 若剩余的元素个数小于 k, 即剩余的元素个数只够一组时,则不用再
* 进行两两归并排序。
*/
while(lowerOfFirGroup + mergeredLength < lengthOfArray)
{
upperOfFirGroup = lowerOfFirGroup + mergeredLength -1;
lowerOfSecGroup = lowerOfFirGroup + mergeredLength;
upperOfSecGroup = (lowerOfSecGroup + mergeredLength - 1 < lengthOfArray)? //比较的三目运算法则
lowerOfSecGroup + mergeredLength - 1 : lengthOfArray-1;
int i = lowerOfFirGroup;
int j = lowerOfSecGroup;
for(i,j; i <= upperOfFirGroup && j <= upperOfSecGroup; count++)
{
if(Array[i] <= Array[j])
{
Swap[count] = Array[i];
i++;
}
else
{
Swap[count] = Array[j];
j++;
}
}
while(i <= upperOfFirGroup)
{
Swap[count] = Array[i];
count++;
i++;
}
while(j <= upperOfSecGroup)
{
Swap[j] = Array[j];
count++;
j++;
}
lowerOfFirGroup = upperOfSecGroup + 1;//换成下一对有序子数组的归并
}
//下面这步是 B(上面的)情况
for(int i = lowerOfFirGroup; i < lengthOfArray; i++,count++)
Swap[count] = Array[i];
}