Here is the program. It takes a hardcoded set of integers and sorts them from least to greatest. I copied it from a book and I can't for the life of my decipher how it does what it does so maybe someone can help me understand.
MAIN
/* Test merge() and mergesort(). */
#include "mergesort.h"
int main(void) {
int sz, key[] = {67, 55, 8, 0, 4, -5, 37, 7, 4, 2, 9, 1, -1};
sz = sizeof(key) / sizeof(int);
printf("Before mergesort:");
wrt(key, sz);
mergesort(key, sz);
printf("After mergesort:");
wrt(key, sz);
return 0;
}
MERGE.C
/* Merge a[] of size m and b[] of size n into c[]. */
#include "mergesort.h"
void merge(int a[], int b[], int c[], int m, int n)
{
int i = 0, j = 0, k = 0;
while (i < m && j < n)
if (a[i] < b[j])
c[k++] = a[i++];
else
c[k++] = b[j++];
while (i < m) /* pick up an remainder */
c[k++] = a[i++];
while (j < n)
c[k++] = b[j++];
}
MERGESORT.C
/* Mergesort: Use merge() to sort an array of size n. */
#include "mergesort.h"
void mergesort(int key[], int n) // n is 0 to begin with
{
int j,k,m, *w;
int x,y;
for (m = 1; m < n; m *= 2) /*m is a power of 2*/
if (n < m){
printf("ERROR: Array size not a power of 2 - bye!\n");
exit(1);
}
w = calloc(m, sizeof(int)); /* allocate workspace */
assert(w != NULL); /* check that calloc() worked */
for (k = 1; k < n; k *= 2) {
for (j = 0; j < n - k; j += 2 * k)
/*
Merge two subarrays of key[] into a subarray of w[].
*/
merge(key + j, key + j + k, w + j, k, k); // todo: make the two k's not equal
for (j = 0; j < n; ++j)
key[j] = w[j];
}
free(w);
}
MERGESORT.H
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
void merge(int a[], int b[], int c[], int m, int n);
void mergesort(int key[], int n);
void wrt(int key[] , int sz);
WRT.C
#include "mergesort.h"
void wrt(int key[], int sz)
{
int i;
for (i = 0; i < sz; ++i)
printf("%4d%s", key[i], ((i < sz - 1) ? "" : "\n"));
}
When it's printed out, there are two zeroes. How is this happening? I think the secret to this lies in mergesort.c, with the k value. As you can see near the bottom, I commented in "todo: make the two k's not equal", this is the simplified solution my teacher offered for me. I also put in the x and y ints which will be the separate k values. But I don't understand, how can I split this one value into two?
The problem is in this part of code of function mergesort()
:
for (m = 1; m < n; m *= 2) /*m is a power of 2*/
if (n < m){
printf("ERROR: Array size not a power of 2 - bye!\n");
exit(1);
}
This is supposed to check whether the size of the array, to be sort, is having the size in power of 2
and the size of the array you are passing is 13
(not the power of 2
):
int sz, key[] = {67, 55, 8, 0, 4, -5, 37, 7, 4, 2, 9, 1, -1};
it should throw error and exit but since the power of 2
check is incorrect it proceeds further and your merge sort code is not capable of sorting an array of uneven size . Hence, you are getting the incorrect output for the array of uneven size.
In the for
loop
for (m = 1; m < n; m *= 2)
^^^^^
the loop will iterate till m < n
and the in the loop body if
condition you are checking
if (n < m){ ....
which will never happen because as soon as m > n
the loop will exit.
Instead of checking the power of 2
, I believe you want to check whether the size of the array is even
or not. To check whether the size is even or not you can simply do:
if (n & 1)
{
printf("ERROR: Array size not a multiple of 2 - bye!\n");
exit(1);
}
For sorting an array using merge sort, it's not required that the size of the array should be even . You can use merge sort to sort an array of odd size as well. Check this answer .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.