求逆序数的快速算法--归并排序
归并排序算法就不多说了。时间复杂度及最坏情况下的时间复杂度为O(NlogN), 空间复杂度为O(N).
存在问题:
1. 附加内存
2. 数据拷贝到临时数组,然后拷贝回来的操作放慢了排序的速度。
因此,对于内存排序,一般用快速排序。
上归并排序的代码:
-
#include<stdio.h>
-
#include<stdlib.h>
-
typedef int ElementType;
-
void Merge(ElementType A[], ElementType TmpArray[], int Lpos, int Rpos, int RightEnd)
-
{
-
int i , LeftEnd, NumElements, TmpPos;
-
LeftEnd = Rpos - 1;
-
TmpPos = Lpos;
-
NumElements = RightEnd - Lpos + 1;
-
while(Lpos <= LeftEnd && Rpos <= RightEnd)
-
{
-
if(A[Lpos] <= A[Rpos])
-
TmpArray[TmpPos++] = A[Lpos++];
-
else
-
{
-
TmpArray[TmpPos++] = A[Rpos++];
-
}
-
}
-
while(Lpos <= LeftEnd)
-
{
-
TmpArray[TmpPos++] = A[Lpos++];
-
}
-
while(Rpos <= RightEnd)
-
{
-
TmpArray[TmpPos++] = A[Rpos++];
-
}
-
for(i = 0; i < NumElements; ++i, --RightEnd)
-
A[RightEnd] = TmpArray[RightEnd];
-
}
-
void MSort(ElementType A[], ElementType TmpArray[], int Left, int Right)
-
{
-
int Center = 0;
-
if(Left < Right)
-
{
-
Center = (Left + Right) >> 1;
-
MSort(A, TmpArray, Left, Center);
-
MSort(A, TmpArray, Center + 1, Right);
-
Merge(A, TmpArray, Left, Center + 1, Right);
-
}
-
}
-
-
void MergeSort(ElementType A[], int N)
-
{
-
ElementType* TmpArray = NULL;
-
-
TmpArray = (ElementType*) malloc(N * sizeof(ElementType));
-
if(NULL != TmpArray)
-
{
-
MSort(A, TmpArray, 0, N - 1);
-
free(TmpArray);
-
}
-
else
-
printf("allocate temp memory fail\n");
-
}
求逆序数的算法
1 逆序数的定义,不多说了,高数应该讲过。
2 求逆序数的算法:
2.1冒泡算法,在冒泡的过程中,没有一个次交换,逆序数加1,理由是冒泡算法交换的是相邻的两个元素,交换后不会影响这两个元素相对于其他元素的逆序的结果(可以把这两个数看做一个整体)。
2.2 归并排序,归并排序把两组有序的数合并起来,而且前一个数组的位置一定小于后一个数组,如果后一个数组中的数比前一个数组中的数小,我们的计数器就需要增加,而增加的量应该是前一个数组的剩余数据的个数(设前一个数组的当前位置为j,长度为n,那么增加量应该是n-j)。
上代码:
-
#include<stdio.h>
-
#include<stdlib.h>
-
typedef int ElementType;
-
int ans;
-
void Merge(ElementType A[], ElementType TmpArray[], int Lpos, int Rpos, int RightEnd)
-
{
-
int i , LeftEnd, NumElements, TmpPos;
-
LeftEnd = Rpos - 1;
-
TmpPos = Lpos;
-
NumElements = RightEnd - Lpos + 1;
-
while(Lpos <= LeftEnd && Rpos <= RightEnd)
-
{
-
if(A[Lpos] <= A[Rpos])
-
TmpArray[TmpPos++] = A[Lpos++];
-
else
-
{
-
ans += (LeftEnd - Lpos + 1);
-
TmpArray[TmpPos++] = A[Rpos++];
-
}
-
}
-
while(Lpos <= LeftEnd)
-
{
-
TmpArray[TmpPos++] = A[Lpos++];
-
}
-
while(Rpos <= RightEnd)
-
{
-
TmpArray[TmpPos++] = A[Rpos++];
-
}
-
for(i = 0; i < NumElements; ++i, --RightEnd)
-
A[RightEnd] = TmpArray[RightEnd];
-
}
-
void MSort(ElementType A[], ElementType TmpArray[], int Left, int Right)
-
{
-
int Center = 0;
-
if(Left < Right)
-
{
-
Center = (Left + Right) >> 1;
-
MSort(A, TmpArray, Left, Center);
-
MSort(A, TmpArray, Center + 1, Right);
-
Merge(A, TmpArray, Left, Center + 1, Right);
-
}
-
}
-
-
void MergeSort(ElementType A[], int N)
-
{
-
ElementType* TmpArray = NULL;
-
-
TmpArray = (ElementType*) malloc(N * sizeof(ElementType));
-
if(NULL != TmpArray)
-
{
-
MSort(A, TmpArray, 0, N - 1);
-
free(TmpArray);
-
}
-
else
-
printf("allocate temp memory fail\n");
-
}
-
void print(int A[], int n)
-
{
-
for(int i = 0; i < n; ++i)
-
printf("%d\t", A[i]);
-
printf("\n");
-
}
-
int main(int argc, char* argv[])
-
{
-
ans = 0;
-
int A[] = { 23, 45, 1, 22, 34,34, 65, 45, 89};
-
MergeSort(A, sizeof(A) / sizeof(A[0]));
-
print(A, sizeof(A) / sizeof(A[0]));
-
printf("ans = %d\n", ans);
-
return 0;
-
}