G
gw7rib
I have written a sorting program, to try to understand how heapsort
works. Unfortunately, considering it's supposed to help my
understanding, one line of it has got very ugly and so I was wondering
if anyone had any advice on how to make it clearer.
The code is C++, but I am rashly cross-posting to comp.lang.c as the
part I am having difficulty with is the same as C and I thought the
peoplr there might also be able to help. You can make it a proper C
program by replacing the definition of n with a #define. I'm aware that
the sort is not actually a heapsort, but I think I know where I'm going
there. I also appreciate that it is only a "toy" program at present and
if I was going to put it to proper use I would be better with a
function pointer for the comparison.
So here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h> // for INT_MAX
const int n = 11;
const int h = (n-1)/2;
typedef int VAL;
const VAL EMPTY = INT_MAX;
/* Special casing would be necessary if n was even. Code also assumes
EMPTY is bigger than real values. */
int main(void) {
int x, y, z, z1, z2;
VAL a[n], b[n], c[n], t;
for (x=0; x < n; x++)
a[x] = rand() % 1000;
printf("Unsorted:");
for (x=0; x < n; x++)
printf(" %d", a[x]);
printf("\n\n");
/* Put values into b, in such a way that b[x] is always less than or
equal to both b[2x+1] and b[2x+2] (where x < h). This can be done
in O(n log n) and could if necessary be done in place in a. */
for (x = 0; x < n; x++) {
t = a[x];
y = x;
while (y > 0 && t < b[z=(y-1)/2]) {
b[y] = b[z];
y = z; }
b[y] = t; }
/* Now pull them out again */
for (x = 0; x < n; x++) {
c[x] = b[0];
y = 0;
while (y < h && (b[z2=2*y+2,z1=2*y+1] < EMPTY || b[z2] < EMPTY)) {
if(b[z1] <= b[z2]) { b[y] = b[z1]; y = z1; }
else { b[y] = b[z2]; y = z2; } }
b[y] = EMPTY; }
printf("Sorted:");
for (x=0; x < n; x++)
printf(" %d", c[x]);
printf("\n\n");
return 0;
}
The snag is with the while statement which sets up the values of z1 and
z2. My first attempt at the program had:
while (y < h && (b[z1=2*y+1] < EMPTY || b[z2=2*y+2] < EMPTY)) {
which is still somewhat messy, but this had the disadvantage of not
working (the program ran forever). The snag with that version is that,
if b[z1] is not empty, the value of z2 does not get set. Hence I have
changed it to the abomination above.
Can anyone advise how to make it clearer?
Thanks for your help.
Paul.
works. Unfortunately, considering it's supposed to help my
understanding, one line of it has got very ugly and so I was wondering
if anyone had any advice on how to make it clearer.
The code is C++, but I am rashly cross-posting to comp.lang.c as the
part I am having difficulty with is the same as C and I thought the
peoplr there might also be able to help. You can make it a proper C
program by replacing the definition of n with a #define. I'm aware that
the sort is not actually a heapsort, but I think I know where I'm going
there. I also appreciate that it is only a "toy" program at present and
if I was going to put it to proper use I would be better with a
function pointer for the comparison.
So here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h> // for INT_MAX
const int n = 11;
const int h = (n-1)/2;
typedef int VAL;
const VAL EMPTY = INT_MAX;
/* Special casing would be necessary if n was even. Code also assumes
EMPTY is bigger than real values. */
int main(void) {
int x, y, z, z1, z2;
VAL a[n], b[n], c[n], t;
for (x=0; x < n; x++)
a[x] = rand() % 1000;
printf("Unsorted:");
for (x=0; x < n; x++)
printf(" %d", a[x]);
printf("\n\n");
/* Put values into b, in such a way that b[x] is always less than or
equal to both b[2x+1] and b[2x+2] (where x < h). This can be done
in O(n log n) and could if necessary be done in place in a. */
for (x = 0; x < n; x++) {
t = a[x];
y = x;
while (y > 0 && t < b[z=(y-1)/2]) {
b[y] = b[z];
y = z; }
b[y] = t; }
/* Now pull them out again */
for (x = 0; x < n; x++) {
c[x] = b[0];
y = 0;
while (y < h && (b[z2=2*y+2,z1=2*y+1] < EMPTY || b[z2] < EMPTY)) {
if(b[z1] <= b[z2]) { b[y] = b[z1]; y = z1; }
else { b[y] = b[z2]; y = z2; } }
b[y] = EMPTY; }
printf("Sorted:");
for (x=0; x < n; x++)
printf(" %d", c[x]);
printf("\n\n");
return 0;
}
The snag is with the while statement which sets up the values of z1 and
z2. My first attempt at the program had:
while (y < h && (b[z1=2*y+1] < EMPTY || b[z2=2*y+2] < EMPTY)) {
which is still somewhat messy, but this had the disadvantage of not
working (the program ran forever). The snag with that version is that,
if b[z1] is not empty, the value of z2 does not get set. Hence I have
changed it to the abomination above.
Can anyone advise how to make it clearer?
Thanks for your help.
Paul.