我尝试使用合并排序在数组中实现多个反转。 每次执行此代码时,都会获得不同数量的取反值。我无法找出原因。请看一下代码,然后告诉我错误。
#include<stdio.h>
#include<iostream>
using namespace std;
int count =0;
void merge(int A[],int start,int mid,int end)
{
int size1 = mid-start+1;
int size2 = end-(mid+1)+1;
int P[size1];
int Q[size2];
for(int i=0;i<size1;i++)
P[i]=A[start+i];
for(int j=0;j<size2;j++)
Q[j]=A[mid+j+1];
int k = 0;
int l = 0;
int i =0;
while(k<mid && l<end)
{
if(P[k]>Q[l])
{
A[i] = Q[l];
l++; i++;
count++;
}
else
{
A[i] = P[k];
k++; i++;
}
}
}
void inversions(int A[],int start,int end)
{
if(start!=end)
{
int mid = (start+end)/2;
inversions(A,start,mid);
inversions(A,mid+1,end);
merge(A,start,mid,end);
}
}
int main()
{
int arr[] = {4,3,1,2,7,5,8};
int n = (sizeof(arr) / sizeof(int));
inversions(arr,0,n-1);
cout<<"The number of inversions is:: "<<count<<endl;
return 0;
}
答案 0 :(得分:0)
int P[size1];
int Q[size2];
C ++不支持VLA(可变长度数组)。 size1
和size2
在编译期间是未知的。因此,每次获得不同的值并因此获得不同的输出。
改为使用std::vector
std::vector<int> P(size1, 0); //initialize with size1 size
std::vector<int> Q(size2, 0); //initialize with size2 size
答案 1 :(得分:0)
int k = 0;
int l = 0;
int i =0;
while(k<mid && l<end)
{
if(P[k]>Q[l])
{
A[i] = Q[l];
l++; i++;
count++;
}
else
{
A[i] = P[k];
k++; i++;
}
}
这里很少出错,i
从start
开始,而不是0
。 k
必须从0
循环到size1
,而不是直到mid
。同样,l
必须从0
循环到size2
,而不是直到end
。您在count
时将1
增加P[k] > Q[l]
,但这是不正确的。请注意,元素P
之后的数组P[k]
中的所有元素都大于Q[l]
。因此,它们也将形成反向对。因此,您应该将计数增加size1-k
。
此外,merge
过程不仅应该计算反转,还应该将两个排序的序列P
和Q
合并到A
中。当while(k<size1 && l<size2)
等于k
或size1
等于l
时,第一个while循环size2
将中断。因此,您必须确保将其他序列的其余部分复制回A
。
我在merge
中进行了适当的更改,并将其粘贴到下面。
void merge(int A[],int start,int mid,int end)
{
int size1 = mid-start+1;
int size2 = end-(mid+1)+1;
int P[size1];
int Q[size2];
for(int i=0;i<size1;i++)
P[i]=A[start+i];
for(int j=0;j<size2;j++)
Q[j]=A[mid+j+1];
int k = 0;
int l = 0;
int i = start;
while(k<size1 && l<size2)
{
if(P[k]>Q[l])
{
A[i] = Q[l];
l++; i++;
count += size1-k;
}
else
{
A[i] = P[k];
k++; i++;
}
}
while (k < size1)
{
A[i] = P[k];
++i, ++k;
}
while (l < size2)
{
A[i] = Q[l];
++i, ++l;
}
}