Iterative Mergesort (9分)
How would you implement mergesort without using recursion?
The idea of iterative mergesort is to start from N sorted sublists of length 1, and each time to merge a pair of adjacent sublists until one sorted list is obtained. You are supposed to implement the key function of merging.
Format of functions:
void merge_pass( ElementType list[], ElementType sorted[], int N, int length );
The function merge_pass
performs one pass of the merge sort
that merges adjacent pairs of sublists from list
into sorted
. N
is
the number of elements in the list
and length
is
the length of the sublists.
Sample program of judge:
#include <stdio.h>
#define ElementType int
#define MAXN 100
void merge_pass( ElementType list[], ElementType sorted[], int N, int length );
void output( ElementType list[], int N )
{
int i;
for (i=0; i<N; i++) printf("%d ", list[i]);
printf("\n");
}
void merge_sort( ElementType list[], int N )
{
ElementType extra[MAXN]; /* the extra space required */
int length = 1; /* current length of sublist being merged */
while( length < N ) {
merge_pass( list, extra, N, length ); /* merge list into extra */
output( extra, N );
length *= 2;
merge_pass( extra, list, N, length ); /* merge extra back to list */
output( list, N );
length *= 2;
}
}
int main()
{
int N, i;
ElementType A[MAXN];
scanf("%d", &N);
for (i=0; i<N; i++) scanf("%d", &A[i]);
merge_sort(A, N);
output(A, N);
return 0;
}
/* Your function will be put here */
Sample Input:
10
8 7 9 2 3 5 1 6 4 0
Sample Output:
7 8 2 9 3 5 1 6 0 4
2 7 8 9 1 3 5 6 0 4
1 2 3 5 6 7 8 9 0 4
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
主要考虑好特殊情况即可
写了两个版本。。第一个比较复杂
version1:
void merge_pass( ElementType list[], ElementType sorted[], int N, int length )
{
int i=0,j=0;
if(length*2<N){
for(i=0;i+2*length-1<N;i=i+2*length){
int count1=0,count2=0;
while(count1<length&&count2<length){
if(list[i+count1]<list[i+length+count2]){
sorted[j++]=list[i+count1];
count1++;
}
else{
sorted[j++]=list[i+length+count2];
count2++;
}
}
while(count1<length){
sorted[j++]=list[i+count1];
count1++;
}
while(count2<length){
sorted[j++]=list[i+length+count2];
count2++;
}
}
if(i+length>=N){
while(i<N)
sorted[j++]=list[i++];}
else{
int count1=0,count2=0;
while(count1<length&&i+length+count2<N){
if(list[i+count1]<list[i+length+count2]){
sorted[j++]=list[i+count1];
count1++;
}
else{
sorted[j++]=list[i+length+count2];
count2++;
}
}
while(count1<length){
sorted[j++]=list[i+count1];
count1++;
}
while(i+length+count2<N){
sorted[j++]=list[i+length+count2];
count2++;
}
}
}
else {
int p=0,q=length;
while(p<length&&q<N){
if(list[p]<list[q]){
sorted[j++]=list[p++];
}
else{
sorted[j++]=list[q++];
}
}
while(p<length){
sorted[j++]=list[p++];
}
while(q<N){
sorted[j++]=list[q++];
}
}
}
version2:
void merge_pass( ElementType list[], ElementType sorted[], int N, int length ){
int i, j, k, p = 0;
for(i = 0; i < N; i += length * 2){
if(i + length * 2 < N){
j = i;
k = j + length;
while(j < i + length&&k < i + 2 * length){
if(list[j] > list[k]){
sorted[p++] = list[k++];
}
else{
sorted[p++] = list[j++];
}
}
while(j < i + length){
sorted[p++] = list[j++];
}
while(k < i + 2 * length){
sorted[p++] = list[k++];
}
}
else if(i+length<N){
j = i;
k = j + length;
while(j < i + length&&k < N){
if(list[j] > list[k]){
sorted[p++] = list[k++];
}
else{
sorted[p++] = list[j++];
}
}
while(j < i + length){
sorted[p++] = list[j++];
}
while(k < N){
sorted[p++] = list[k++];
}
}
else{
j = i;
while(j < N){
sorted[p++] = list[j++];
}
}
}
}