打算学习一下算法,这几天没有时间。
今天接着分治算法实现继续往下走。
修改了一下分治算法,实现了逆序对。
逆序对其实很简单,就是看分治算法的时候,对于那两个已经排好序的数组进行组合过程需要交换的次数,当然了其中还包含了交换的距离。
代码很简单,也没有细写,随便改了一下。
#include "InversionPair.h"
static int s_iTotal = 0;
static void SortInOrder(int *piArray, int iFromA, int iToA, int iFromB, int iToB, int *pA, int *pB)
{
int iLoop, jLoop;
int iSizeA, iSizeB;
int *pTmp;
int iIdex = 0;
iSizeA = iToA - iFromA + 1;
iSizeB = iToB - iFromB + 1;
for(iLoop = 0; iLoop < iSizeA; iLoop++) {
pA[iLoop] = piArray[iFromA + iLoop];
}
for(iLoop = 0; iLoop < iSizeB; iLoop++) {
pB[iLoop] = piArray[iFromB + iLoop];
}
pTmp = piArray + iFromA;
for(iLoop = 0, jLoop = 0; iLoop < iSizeA && jLoop < iSizeB; ) {
//前小后大
if(pA[iLoop] > pB[jLoop]) {
s_iTotal += jLoop + iSizeA - iIdex;
*pTmp = pB[jLoop];
jLoop++;
} else {
*pTmp = pA[iLoop];
iLoop++;
}
pTmp++;
iIdex++;
}
if(iLoop == iSizeA) {
for(; jLoop < iSizeB; jLoop++, pTmp++) {
*pTmp = pB[jLoop];
}
}
if(jLoop == iSizeB) {
for(; iLoop < iSizeA; iLoop++, pTmp++) {
*pTmp = pA[iLoop];
}
}
}
static void PartitionPart(int * piArray, int iFrom, int iTo, int *pA, int *pB)
{
if(iTo - iFrom <= 3) { //只有两个元素的时候
int iTmp;
int iLoop;
int jLoop;
for(iLoop = iFrom + 1; iLoop <= iTo; iLoop++) {
for(jLoop = iLoop - 1; jLoop >= iFrom; jLoop--) {
if(piArray[jLoop] <= piArray[jLoop + 1]) {
break;
}
s_iTotal++;
iTmp = piArray[jLoop + 1];
piArray[jLoop + 1] = piArray[jLoop];
piArray[jLoop] = iTmp;
}
}
return ;
}
int iCenter = (iTo - iFrom) / 2 + iFrom;
PartitionPart(piArray, iFrom, iCenter, pA, pB);
PartitionPart(piArray, iCenter + 1, iTo, pA, pB);
SortInOrder(piArray, iFrom, iCenter, iCenter + 1, iTo, pA, pB);
}
//利用分治算法进行排序
int InversionPair(const int * piArray, int iSize)
{
int *pA, *pB;
int *piArrayTmp;
s_iTotal = 0;
pA = (int *) malloc((iSize + 1) / 2 * sizeof(int));
pB = (int *) malloc((iSize + 1) / 2 * sizeof(int));
//这里不改变原来的值
piArrayTmp = (int *) malloc(iSize * sizeof(int));
if(pA == NULL || pB == NULL || piArrayTmp == NULL) {
printf("malloc error:%s %d/n", __FILE__, __LINE__);
exit(-1);
}
memcpy(piArrayTmp, piArray, iSize * sizeof(int));
PartitionPart(piArrayTmp, 0, iSize - 1, pA, pB);
free(piArrayTmp);
free(pB);
free(pA);
return s_iTotal;
}