求逆序数的快速算法--归并排序

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

存在问题:

1. 附加内存

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

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

上归并排序的代码:

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

 

求逆序数的算法

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

2 求逆序数的算法:

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

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

上代码:

隐藏行号 复制代码 这是一段程序代码。
  1. #include
    
  2. #include
    
  3.  
  4. typedef int ElementType;
    
  5. int ans;    
    
  6.  
  7. void Merge(ElementType A[], ElementType TmpArray[], int Lpos, int Rpos, int RightEnd)
    
  8. {
    
  9.     int i , LeftEnd, NumElements, TmpPos;
    
  10.  
  11.     LeftEnd = Rpos - 1;
    
  12.     TmpPos = Lpos;
    
  13.     NumElements = RightEnd - Lpos + 1;
    
  14.  
  15.     while(Lpos <= LeftEnd && Rpos <= RightEnd)
    
  16.     {
    
  17.         if(A[Lpos] <= A[Rpos])
    
  18.             TmpArray[TmpPos++] = A[Lpos++];
    
  19.         else
    
  20.         {
    
  21.             ans += (LeftEnd - Lpos + 1); 
    
  22. TmpArray[TmpPos++] = A[Rpos++];
    
  23.         }
    
  24.     }
    
  25.  
  26.     while(Lpos <= LeftEnd) 
    
  27.     {
    
  28. TmpArray[TmpPos++] = A[Lpos++];
    
  29.     }
    
  30.  
  31.     while(Rpos <= RightEnd)
    
  32.     {
    
  33.         TmpArray[TmpPos++] = A[Rpos++];
    
  34.     }
    
  35.  
  36.     for(i = 0; i < NumElements; ++i, --RightEnd)
    
  37.         A[RightEnd] = TmpArray[RightEnd];
    
  38. }
    
  39.  
  40. void MSort(ElementType A[], ElementType TmpArray[], int Left, int Right)
    
  41. {
    
  42.     int Center = 0;
    
  43.     if(Left < Right)
    
  44.     {
    
  45.         Center = (Left + Right) >> 1;
    
  46.         MSort(A, TmpArray, Left, Center);
    
  47.         MSort(A, TmpArray, Center + 1, Right);
    
  48.         Merge(A, TmpArray, Left, Center + 1, Right);
    
  49.     }
    
  50. }
    
  51.  
    
  52. void MergeSort(ElementType A[], int N)
    
  53. {
    
  54.     ElementType* TmpArray = NULL;
    
  55.     
    
  56.     TmpArray = (ElementType*) malloc(N * sizeof(ElementType));
    
  57.     if(NULL != TmpArray)
    
  58.     {
    
  59.         MSort(A, TmpArray, 0, N - 1);
    
  60.         free(TmpArray);
    
  61.     }
    
  62.     else
    
  63.         printf("allocate temp memory fail\n");
    
  64. }
    
  65.  
  66. void print(int A[], int n)
    
  67. {
    
  68.     for(int i = 0; i < n; ++i)
    
  69.         printf("%d\t", A[i]);
    
  70.     printf("\n");
    
  71. }
    
  72.  
  73. int main(int argc, char* argv[])
    
  74. {
    
  75.     ans = 0;
    
  76.     int A[] = { 23, 45, 1, 22, 34,34, 65, 45, 89};
    
  77.     MergeSort(A, sizeof(A) / sizeof(A[0]));
    
  78.     print(A, sizeof(A) / sizeof(A[0]));
    
  79.     printf("ans = %d\n", ans);
    
  80.     return 0;
    
  81. }
    

你可能感兴趣的:(求逆序数的快速算法--归并排序)