这题是要求冒泡排序交换的次数,数据这么大,直接冒泡排序肯定超时,这题实际就是求逆序对数,可以用归并排序来求逆序对数,

只需要在代码注视处加上cnt+=m-p就可以了。

//归并排序求逆序对数
#include <iostream>
using namespace std;
int cnt=0;
// 归并排序中的合并算法
void Merge(int a[], int left, int center, int len)
{
int *t = (int *) malloc((len-left+1) * sizeof(int)); //申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
int i = left;
int j = center;
int k = 0;
while (i<center && j<len) //比较两个指针所 指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
{
if (a[i] <= a[j])
t[k
++] = a[i++];
else
   {
    t[k
++] = a[j++];
    
//如果后面的数要前移,说明前半部分的后面的数原先是大于后半部分的那个数的,等于center-i,
    
//因为每部分数组是有序的。
    cnt+=center-i;
   }
}
while (i < center) //若第一个序列有剩余,直接拷贝出来粘到合并序列尾
t[k++] = a[i++];
while (j < len) //若第二个序列有剩余,直接拷贝出来粘到合并序列尾
    t[k++] = a[j++];

//将排序好的序列拷贝回数组中
for (i=left,k=0; i<len; i++,k++)
a[i]
= t[k];

free(t);
}


// 归并排序
void MSort(int a[], int left, int right)
{
if (left < right)
{
int center = (left + right) / 2;
// 对前半部分进行排序
   MSort(a, left, center);
  
// 对后半部分进行排序
MSort(a, center+1, right);
  
// 合并前后两部分
Merge(a, left, center+1, right+1);
}
}

void MergeSort(int a[], int n)
{
MSort(a,
0, n-1);
//=================================
for(int i=0;i<n;i++)
{
if(i%5==0)
cout
<<endl;
cout
<<a[i]<<" ";
}
cout
<<endl;
}

int main()
{
FILE
*fin=fopen("8.1.2.txt","r");
int num[80],i=0;
while(fscanf(fin,"%d",&num[i])!=EOF)
i
++;
MergeSort(num,i);
cout
<<cnt<<endl;
fclose(fin);
return 0;
}

 

相关文章:

  • 2022-12-23
  • 2022-02-04
  • 2021-05-14
  • 2021-11-10
  • 2021-08-08
  • 2022-01-20
  • 2018-04-24
  • 2022-12-23
猜你喜欢
  • 2021-08-14
  • 2021-10-21
  • 2021-11-19
  • 2022-01-18
  • 2022-12-23
  • 2021-08-29
  • 2021-12-22
相关资源
相似解决方案