两路合并
时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte
总提交:338 测试通过:206
总提交:338 测试通过:206
描述
给定输入排序元素数目n和相应的n个元素,写出程序,利用内排序算法中两路合并排序算法进行排序,并输出排序最后结果的相应序列。
输入
共两行,第一行给出排序元素数目n,第二行给出n个元素,1≤n≤100000,每个元素值范围为 [0,100000)
输出
一行,输出排序结果。
样例输入
7
48 36 68 72 12 48 2
样例输出
2 12 36 48 48 68 72
提示
数据结构A实验四
题目来源
CHENZ
分析:标准C++写法。
#include<stdio.h>
//两路合并
int a[100000];
void merge(int a[], int i1, int j1, int i2, int j2)
{
int i = i1, j = i2;
int *tmp = new int[j2-i1+1];
int k = 0;
while(i <= j1 && j <= j2)
{
if(a[i] <= a[j])
tmp[k++] = a[i++];
else
tmp[k++] = a[j++];
}
while(i <= j1)
tmp[k++] = a[i++];
while(j <= j2)
tmp[k++] = a[j++];
for(int i=0;i<k;i++)
a[i1++] = tmp[i];
delete tmp;
}
void mergesort(int a[], int n)
{
int i1, j1, i2, j2; // i1,j1是子序列1的下、上界;i2、j2是子序列2的下、上界
int size = 1;
while(size < n)
{
i1 = 0;
while(i1+size < n) // 存在2个子序列
{
i2 = i1+size;
j1 = i2-1;
if(i2+size-1 > n-1) // 第2个子序列中不足size个元素
j2 = n-1;
else
j2 = i2+size-1; // 第2个子序列中有size个元素
merge(a, i1, j1, i2, j2); // 合并相邻两个子序列
i1 = j2+1; // 确定下一次合并第1个子序列的下界
}
size *= 2; // 元素个数扩大一倍
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
mergesort(a, n);
for(int i=0;i<n-1;i++)
printf("%d ",a[i]);
printf("%d\n",a[n-1]);
return 0;
}