#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
void merge(int* a, int low, int mid, int hight) //合并函数
{
int* b = new int[hight - low + 1]; //用 new 申请一个辅助函数
int i = low, j = mid + 1, k = 0; // k为 b 数组的小标
while (i <= mid && j <= hight)
{
if (a[i] <= a[j])
{
b[k++] = a[i++]; //按从小到大存放在 b 数组里面
}
else
{
b[k++] = a[j++];
}
}
while (i <= mid) // j 序列结束,将剩余的 i 序列补充在 b 数组中
{
b[k++] = a[i++];
}
while (j <= hight)// i 序列结束,将剩余的 j 序列补充在 b 数组中
{
b[k++] = a[j++];
}
k = 0; //从小标为 0 开始传送
for (int i = low; i <= hight; i++) //将 b 数组的值传递给数组 a
{
a[i] = b[k++];
}
delete[]b; // 辅助数组用完后,将其的空间进行释放(销毁)
}
void mergesort(int* a, int low, int hight) //归并排序
{
if (low < hight)
{
int mid = (low + hight) / 2;
mergesort(a, low, mid); //对 a[low,mid]进行排序
mergesort(a, mid + 1, hight); //对 a[mid+1,hight]进行排序
merge(a, low, mid, hight); //进行合并操作
}
}
int main()
{
int n, a[100];
cout << "请输入数列中的元素个数 n 为:" << endl;
cin >> n;
cout << "请依次输入数列中的元素:" << endl;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
mergesort(a, 0, n-1);
cout << "归并排序结果" << endl;
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
cout << endl;
return 0;
}
逆序列对数求解
有一个长度为 n 的数组 求该序列的逆序对个数。
输入格式:
第一行,一个数 n,表示序列中有 n个数
第二行 n 个数,表示给定的序列,序列中每个数字不超过 1e9输出格式:
输出序列中逆序对的数目。
输入样例:
6 5 4 2 6 3 1
#include<iostream>
using namespace std;
const int N=100010;
int q[N],t[N],n;
int res;//假如按照逆序对最多的情况,也就是倒序,例:5 4 3 2 1。
void merge_sort(int l,int r)
{
if(l>=r) return;
int mid=int (l+r)/2;
merge_sort(l,mid),merge_sort(mid+1,r);// “分”
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r)
{
if(q[i]<=q[j]) t[k++]=q[i++];
else
{
t[k++]=q[j++];
res+=mid-i+1;// “治”
}
}
while(i<=mid) t[k++]=q[i++];//收尾:假如左端或者右端先填完了,得把另一端的数都加上。
while(j<=r) t[k++]=q[j++];
for(i=l,j=0;i<=r;i++,j++) q[i]=t[j];
}int main()
{
cin >> n;
for(int i=0;i<n;i++) cin >> q[i];
merge_sort(0,n-1);
cout << res << endl;
return 0;
}