#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
//合并排序的合并程序他合并数组nData中位置为[nP,nM) 和[nM,nR).这个是更接近标准的思路
bool MergeStandard(int nData[], int nP, int nM, int nR)
{
int n1 = nM - nP; //第一个合并数据的长度
int n2 = nR - nM; //第二个合并数据的长度
int *pnD1 = new int[n1 + 1]; //申请一个保存第一个数据的空间
int *pnD2 = new int[n2 + 1]; //申请二个保存第一个数据的空间
for (int i = 0; i < n1; ++i) //复制第一个数据到临时空间里面
{
pnD1[i] = nData[nP + i];
}
pnD1[n1] = INT_MAX; //将最后一个数据设置为最大值(哨兵)
for (int j = 0; j < n2; ++j) //复制第二个数据到临时空间里面
{
pnD2[j] = nData[nM + j];
}
pnD2[n2] = INT_MAX; //将最后一个数据设置为最大值(哨兵)
n1 = n2 = 0;
while(nP < nR)
{
nData[nP++] = pnD1[n1] < pnD2[n2] ? pnD1[n1++] : pnD2[n2++]; //取出当前最小值到指定位置
}
delete pnD1;
delete pnD2;
return true;
}
//合并排序的合并程序他合并数组nData中位置为[nP,nM) 和[nM,nR).
bool Merge(int nData[], int nP, int nM, int nR)
{
//这里面有几个注释语句是因为当时想少写几行而至。看似短了,其实运行时间是一样的,而且不易阅读。
int nLen1 = nM - nP; //第一个合并数据的长度
int nLen2 = nR - nM; //第二个合并数据的长度
int* pnD1 = new int[nLen1]; //申请一个保存第一个数据的空间
int* pnD2 = new int[nLen2]; //申请一个保存第一个数据的空间
int i = 0;
for ( i = 0; i < nLen1; ++i) //复制第一个数据到临时空间里面
{
pnD1[i] = nData[nP + i];
}
int j = 0;
for (j = 0; j < nLen2; ++j) //复制第二个数据到临时空间里面
{
pnD2[j] = nData[nM + j];
}
i = j = 0;
while (i < nLen1 && j < nLen2)
{
//nData[nP++] = pnD1[i] < pnD2[j] ? pnD1[i++] : pnD2[j++]; //取出当前最小值添加到数据中
if (pnD1[i] < pnD2[j]) //取出最小值,并添加到指定位置中,如果pnD1[i] < pnD2[j]
{
nData[nP] = pnD1[i]; //取出pnD1的值,然后i++,定位到下一个个最小值。
++i;
}
else //这里同上
{
nData[nP] = pnD2[j];
++j;
}
++nP; //最后np++,到确定下一个数据
}
if (i < nLen1) //如果第一个数据没有结束(第二个数据已经结束了)
{
while (nP < nR) //直接把第一个剩余的数据加到nData的后面即可。
{
//nData[nP++] = pnD1[i++];
nData[nP] = pnD1[i];
++nP;
++i;
}
}
else //否则(第一个结束,第二个没有结束)
{
while (nP < nR) //直接把第一个剩余的数据加到nData的后面即可。
{
//nData[nP++] = pnD2[j++];
nData[nP] = pnD2[j];
++nP;
++j;
}
}
delete pnD1; //释放申请的内存空间
delete pnD2;
return true;
}
//合并的递归调用,排序[nBegin, nEnd)区间的内容
bool MergeRecursion(int nData[], int nBegin, int nEnd)
{
if (nBegin >= nEnd - 1) //已经到最小颗粒了,直接返回
{
return false;
}
int nMid = (nBegin + nEnd) / 2; //计算出他们的中间位置,便于分治
MergeRecursion(nData, nBegin, nMid); //递归调用,合并排序好左边一半
MergeRecursion(nData, nMid, nEnd); //递归调用,合并排序好右边一半
//Merge(nData, nBegin, nMid, nEnd); //将已经合并排序好的左右数据合并,时整个数据排序完成
MergeStandard(nData, nBegin, nMid, nEnd);//(用更接近标准的方法合并)
return true;
}
//合并排序
bool MergeSort(int nData[], int nNum)
{
return MergeRecursion(nData, 0, nNum); //调用递归,完成合并排序
}
int main()
{
int nData[10] = {4,10,3,8,5,6,7,4,9,2}; //创建10个数据,测试
MergeSort(nData,10);
for (int i=0;i<10;i++)
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}
合并排序
最新推荐文章于 2022-11-27 14:28:13 发布