使用Mergesort计算C ++中的反转次数 [英] Using Mergesort to calculate number of inversions in C++

查看:145
本文介绍了使用Mergesort计算C ++中的反转次数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

void MergeSort(int A[], int n, int B[], int C[])
{ 
    if(n > 1)
    {
       Copy(A,0,floor(n/2),B,0,floor(n/2));
       Copy(A,floor(n/2),n-1,C,0,floor(n/2)-1);
       MergeSort(B,floor(n/2),B,C);
       MergeSort(C,floor(n/2),B,C);
       Merge(A,B,0,floor(n/2),C,0,floor(n/2)-1);
    }
};

void Copy(int A[], int startIndexA, int endIndexA, int B[], int startIndexB, int endIndexB)
{
    while(startIndexA < endIndexA && startIndexB < endIndexB)
    {
        B[startIndexB]=A[startIndexA];
        startIndexA++;
        startIndexB++;
    }
 };

 void Merge(int A[], int B[],int leftp, int rightp, int C[], int leftq, int rightq) 
//Here each sub array (B and C) have both left and right indices variables (B is an array with p elements and C is an element with q elements)
{ 
    int i=0;
    int j=0;
    int k=0;

    while(i < rightp && j < rightq)
    {
        if(B[i] <=C[j])
        {
            A[k]=B[i];
            i++;
        }
       else
       {
            A[k]=C[j];
            j++;
            inversions+=(rightp-leftp); //when placing an element from the right array, the number of inversions is the number of elements still in the left sub array.
        }
        k++;
  }
  if(i=rightp)
      Copy(A,k,rightp+rightq,C,j,rightq);
  else
      Copy(A,k,rightp+rightq,B,i,rightp);
}



我特别困惑于第二个'B'和'C'的效果'参数在MergeSort调用。我需要他们在那里,所以我可以访问他们的副本和合并,但

I am specifically confused on the effect of the second 'B' and 'C' arguments in the MergeSort calls. I need them in there so I have access to them for Copy and and Merge, but

我对这里的歧义道歉。这是输出:

I apologize for the ambiguity here. Here is the output:

Input (A)=  4   2   53  8   1   19  21   6 
 19 
 19 
 21  
 19 
 21 
 19 
 21 
 6 
 inversions=9

显然,这不是数组的正确结果,根据我的计数,反转应该等于16.任何帮助或意见将非常感谢。 (甚至批评太!)

Obviously that is not the correct result for the array, and by my count, the inversions should equal 16. Any help or comments would be greatly appreciated. (even criticism too! ;)

推荐答案

算法介绍中的伪代码(Cormen。MIT Press) p>

Psuedo-code from Intro to Algorithms (Cormen. MIT Press) 2nd Edition:

MERGE -INVERSIONS ( A, p, q, r)
n1 ← q − p + 1
n2 ← r − q
create arrays L[1 . . n1 + 1] and R[1 . . n2 + 1]
for i ← 1 to n1
  do L[i] ← A[ p + i − 1]
for j ← 1 to n2
  do R[ j ] ← A[q + j ]
L[n 1 + 1] ← ∞
R[n 2 + 1] ← ∞
i ←1
j ←1
inversions ← 0
counted ← FALSE
for k ← p to r
  do 
  if counted = FALSE and R[ j ] < L[i]
    then inversions ← inversions +n1 − i + 1
    counted ← TRUE
  if L[i] ≤ R[ j ]
    then A[k] ← L[i]
    i ←i +1
  else A[k] ← R[ j ]
    j ← j +1
    counted ← FALSE
  return inversions

应该注意,计数变量实际上不需要。合并排序本质上是一个固有的递归算法。你的实现应该紧跟这个伪代码。同时根据需要适应您的需要。然而在这种情况下。直接实现这个伪代码将会在经典的合并排序期间计数倒数。

One should note that the counted variable is actually not needed. Merge sort is an inherently recursive algorithm by nature. Your implementation should closely follow this psuedo-code. While adapting where necessary to suit your needs. However in this case. A direct implementation of this psuedo-code will in fact count inversions during a classic merge sort.

这篇关于使用Mergesort计算C ++中的反转次数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆