Write a program of a Merge Sort algorithm implemented by the following pseudocode. You should also report the number of comparisons in the Merge function.
Merge(A, left, mid, right)
n1 = mid - left;
n2 = right - mid;
create array L[0...n1], R[0...n2]
for i = 0 to n1-1
do L[i] = A[left + i]
for i = 0 to n2-1
do R[i] = A[mid + i]
L[n1] = SENTINEL
R[n2] = SENTINEL
i = 0;
j = 0;
for k = left to right-1
if L[i] <= R[j]
then A[k] = L[i]
i = i + 1
else A[k] = R[j]
j = j + 1
Merge-Sort(A, left, right){
if left+1 < right
then mid = (left + right)/2;
call Merge-Sort(A, left, mid)
call Merge-Sort(A, mid, right)
call Merge(A, left, mid, right
Input
In the first line n is given. In the second line, n integers are given.
Output
In the first line, print the sequence S. Two consequtive elements should be separated by a space character.
In the second line, print the number of comparisons.
Constraints
- n ≤ 500000
- 0 ≤ an element in S ≤ 109
Sample Input 1
10
8 5 9 2 6 3 7 1 10 4
Sample Output 1
1 2 3 4 5 6 7 8 9 10
34
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn=500005;
const int INF=0x3f3f3f3f;
int n;
int a[maxn];
int cnt=0;
void Sort (int left,int mid,int right)
{
int L[(maxn>>1)+10],R[(maxn>>1)+10];
int numl=mid-left;
int numr=right-mid;
for (int i=0;i<numl;i++)
L[i]=a[i+left];
for (int i=0;i<numr;i++)
R[i]=a[i+mid];
L[numl]=R[numr]=INF;
for (int i=left,j=0,k=0;i<right;i++)
{
cnt++;
a[i]=L[j]<R[k]?L[j++]:R[k++];
}
}
//先进行分治,当分治到不能分治的时候进行回溯排序
void Merge (int left,int right)
{
if(left+1<right)
{
int mid=(left+right)>>1;
Merge (left,mid);
Merge (mid,right);
Sort (left,mid,right);
}
}
int main()
{
scanf("%d",&n);
for (int i=0;i<n;i++)
scanf("%d",&a[i]);
Merge (0,n);
for (int i=0;i<n;i++)
printf("%d%c",a[i],i==n-1?'\n':' ');
printf("%d\n",cnt);
return 0;
}