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
结尾无空行
解题思路:
这道题的思路跟归并排序的思路类似,不过归并排序用到递归,此题用到迭代的思想。
length是每次排序的时候需要分成length长度的块,比如说传入8 7 9 2 3 5 1 6 这个序列,如果给定的length为1,
那么需要将此序列分成10个块,如图:
设置a指向第i个block的头部,aa指向第i个block的尾部,b指向第i+length个block的头部,bb指向第i+length*2个block的尾部。
如果出现aa>N或者bb>N的情况,那么越界,将aa或者bb更改为N;
然后进入while循环,接下来的步骤便和归并排序类似,比list[a]和list[b]的大小,谁小就将它放入sorted[]中,直到a排完或者b排完。
i每次+=length*2,即每次比较两个块。

void merge_pass(ElementType list[], ElementType sorted[], int N, int length) { for (int i = 0; i < N; i+=length*2) { int j = 0, a = i, b = i + length, aa = i + length, bb = i + length * 2; if (aa > N)aa = N; if (bb > N)bb = N; while (a<aa&&b<bb) { if (list[a] > list[b]) { sorted[i + j++] = list[b++]; } else { sorted[i + j++] = list[a++]; } } while (a < aa) { sorted[i + j++] = list[a++]; } while (b < bb) { sorted[i + j++] = list[b++]; } } }