排序-归并排序与求逆序数的算法--转帖-长见识了

一直以为归并排序就只能排序用了,原来还有这么一个用处,以O(NlogN)的时间复杂度来求一个数组的总的逆序数。

长见识了。

 

归并排序算法就不多说了。时间复杂度及最坏情况下的时间复杂度为O(NlogN), 空间复杂度为O(N).

存在问题:

1. 附加内存

2. 数据拷贝到临时数组,然后拷贝回来的操作放慢了排序的速度。

因此,对于内存排序,一般用快速排序。

上归并排序的代码:

隐藏行号 复制代码 归并排序
  1. #include
    
  2. #include
    
  3. typedef int ElementType;  
    
  4. void Merge(ElementType A[], ElementType TmpArray[], int Lpos, int Rpos, int RightEnd)
    
  5. {
    
  6.     int i , LeftEnd, NumElements, TmpPos;
    
  7.     LeftEnd = Rpos - 1;
    
  8.     TmpPos = Lpos;
    
  9.     NumElements = RightEnd - Lpos + 1;
    
  10.     while(Lpos <= LeftEnd && Rpos <= RightEnd)
    
  11.     {
    
  12.         if(A[Lpos] <= A[Rpos])
    
  13.             TmpArray[TmpPos++] = A[Lpos++];
    
  14.         else
    
  15.         { 
    
  16.             TmpArray[TmpPos++] = A[Rpos++];
    
  17.         }
    
  18.     }
    
  19.     while(Lpos <= LeftEnd) 
    
  20.     {    
    
  21.         TmpArray[TmpPos++] = A[Lpos++];
    
  22.     }
    
  23.     while(Rpos <= RightEnd)
    
  24.     {
    
  25.         TmpArray[TmpPos++] = A[Rpos++];
    
  26.     }
    
  27.     for(i = 0; i < NumElements; ++i, --RightEnd)
    
  28.         A[RightEnd] = TmpArray[RightEnd];
    
  29. }
    
  30. void MSort(ElementType A[], ElementType TmpArray[], int Left, int Right)
    
  31. {
    
  32.     int Center = 0;
    
  33.     if(Left < Right)
    
  34.     {
    
  35.         Center = (Left + Right) >> 1;
    
  36.         MSort(A, TmpArray, Left, Center);
    
  37.         MSort(A, TmpArray, Center + 1, Right);
    
  38.         Merge(A, TmpArray, Left, Center + 1, Right);
    
  39.     }
    
  40. }
    
  41.  
    
  42. void MergeSort(ElementType A[], int N)
    
  43. {
    
  44.     ElementType* TmpArray = NULL;
    
  45.     
    
  46.     TmpArray = (ElementType*) malloc(N * sizeof(ElementType));
    
  47.     if(NULL != TmpArray)
    
  48.     {
    
  49.         MSort(A, TmpArray, 0, N - 1);
    
  50.         free(TmpArray);
    
  51.     }
    
  52.     else
    
  53.         printf("allocate temp memory fail/n");
    
  54. }
    

 

求逆序数的算法

1 逆序数的定义,不多说了,高数应该讲过。

2 求逆序数的算法:

2.1冒泡算法,在冒泡的过程中,没有一个次交换,逆序数加1,理由是冒泡算法交换的是相邻的两个元素,交换后不会影响这两个元素相对于其他元素的逆序的结果(可以把这两个数看做一个整体)。

2.2 归并排序,归并排序把两组有序的数合并起来,而且前一个数组的位置一定小于后一个数组,如果后一个数组中的数比前一个数组中的数小,我们的计数器就需要增加,而增加的量应该是前一个数组的剩余数据的个数(设前一个数组的当前位置为j,长度为n,那么增加量应该是n-j)。

上代码:

隐藏行号 复制代码 这是一段程序代码。
  1. #include
    
  2. #include
    
  3. typedef int ElementType;
    
  4. int ans;    
    
  5.  
  6. void Merge(ElementType A[], ElementType TmpArray[], int Lpos, int Rpos, int RightEnd)
    
  7. {
    
  8.     int i , LeftEnd, NumElements, TmpPos;
    
  9.     LeftEnd = Rpos - 1;
    
  10.     TmpPos = Lpos;
    
  11.     NumElements = RightEnd - Lpos + 1;
    
  12.     while(Lpos <= LeftEnd && Rpos <= RightEnd)
    
  13.     {
    
  14.         if(A[Lpos] <= A[Rpos])
    
  15.             TmpArray[TmpPos++] = A[Lpos++];
    
  16.         else
    
  17.         {
    
  18.             ans += (LeftEnd - Lpos + 1); 
    
  19.             TmpArray[TmpPos++] = A[Rpos++];
    
  20.         }
    
  21.     }
    
  22.     while(Lpos <= LeftEnd) 
    
  23.     {
    
  1. TmpArray[TmpPos++] = A[Lpos++];
  1.     }
    
  2.     while(Rpos <= RightEnd)
    
  3.     {
    
  4.         TmpArray[TmpPos++] = A[Rpos++];
    
  5.     }
    
  6.     for(i = 0; i < NumElements; ++i, --RightEnd)
    
  7.         A[RightEnd] = TmpArray[RightEnd];
    
  8. }
    
  9. void MSort(ElementType A[], ElementType TmpArray[], int Left, int Right)
    
  10. {
    
  11.     int Center = 0;
    
  12.     if(Left < Right)
    
  13.     {
    
  14.         Center = (Left + Right) >> 1;
    
  15.         MSort(A, TmpArray, Left, Center);
    
  16.         MSort(A, TmpArray, Center + 1, Right);
    
  17.         Merge(A, TmpArray, Left, Center + 1, Right);
    
  18.     }
    
  19. }
    
  20.  
    
  21. void MergeSort(ElementType A[], int N)
    
  22. {
    
  23.     ElementType* TmpArray = NULL;
    
  24.     
    
  25.     TmpArray = (ElementType*) malloc(N * sizeof(ElementType));
    
  26.     if(NULL != TmpArray)
    
  27.     {
    
  28.         MSort(A, TmpArray, 0, N - 1);
    
  29.         free(TmpArray);
    
  30.     }
    
  31.     else
    
  32.         printf("allocate temp memory fail/n");
    
  33. }
    
  34. void print(int A[], int n)
    
  35. {
    
  36.     for(int i = 0; i < n; ++i)
    
  37.         printf("%d/t", A[i]);
    
  38.     printf("/n");
    
  39. }
    
  40. int main(int argc, char* argv[])
    
  41. {
    
  42.     ans = 0;
    
  43.     int A[] = { 23, 45, 1, 22, 34,34, 65, 45, 89};
    
  44.     MergeSort(A, sizeof(A) / sizeof(A[0]));
    
  45.     print(A, sizeof(A) / sizeof(A[0]));
    
  46.     printf("ans = %d/n", ans);
    
  47.     return 0;
    
  48. }

你可能感兴趣的:(排序-归并排序与求逆序数的算法--转帖-长见识了)