归并排序算法就不多说了。时间复杂度及最坏情况下的时间复杂度为O(NlogN), 空间复杂度为O(N).
存在问题:
1. 附加内存
2. 数据拷贝到临时数组,然后拷贝回来的操作放慢了排序的速度。
因此,对于内存排序,一般用快速排序。
上归并排序的代码:
#include
#include
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
#include
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;
}