473,714 Members | 2,552 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Merge Sort in C - array output is same as input after sort routine completes

rkk
Hi,

I have written a generic mergesort program which is as below:
---------------------------------------------------------
mergesort.h
-----------------------

void
MergeSort(void *array[],int p,int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB));
void
Merge(void *array[],int p,int q, int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB));
int
IntegerComp(con st void *keyA,const void *keyB);

mergesort.c
--------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mergesort. h"
void
MergeSort(void *array[],int p,int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB))
{
int q;
if(p < r) {
q = (p + r)/2;
MergeSort(array ,p,q,elemSize,C ompare);
MergeSort(array ,q + 1,r,elemSize,Co mpare);
Merge(array,p,q ,r,elemSize,Com pare);
}
}

void
Merge(void *array[],int p,int q, int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB))
{
void **out = (void **)malloc(elemS ize * r);
int i,k,j;
i = k = p;
j = q + 1;
while( i <= q && j <= r ) {
if( Compare( &array[i * elemSize],&array[j * elemSize] ) <= 0 ) {
out[k++] = array[i++];
} else {
out[k++] = array[j++];
}
}
while( i <= q ) out[k++] = array[i++];
while( j <= r ) out[k++] = array[j++];

for (i = p;i < r; i++) {
array[i] = out[i];
}
free(out);
}
int
IntegerComp(con st void *keyA,const void *keyB)
{
if( (const int *) keyA == (const int *) keyB ) return 0;
else if( (const int *) keyA < (const int *) keyB ) return -1;
else if( (const int *) keyA (const int *) keyB ) return 1;
}
----------------------------------------------
And the driver program is here:
test.c
---------
#include <stdio.h>
#include "mergesort. h"

int
main()
{
int idx,length;
int arr[] = { 2,21,1,48,15,31 ,26 };
length = sizeof arr/sizeof &arr[0];

printf("Before sorting array:\n");
for (idx = 0;idx < length;idx++)
{
printf("%d ",arr[idx]);
}
printf("\n");

MergeSort(&arr, 0,length,sizeof (int),IntegerCo mp);

printf("After sorting array:\n");
for (idx = 0;idx < length;idx++)
{
printf("%d ",arr[idx]);
}
printf("\n");
return 0;
}
----------------------------------------------------------
I compile the programs above as:

gcc -g -o mergesort mergesort.c test.c

The output is little surprising as the array looks unsorted after sort
algorithm is completed. I am not understanding what's going wrong here,
kindly help me.:
kalyan@proteus mergesort
Before sorting array:
2 21 1 48 15 31 26
After sorting array:
2 21 1 48 15 31 26

Thank you.

Regards
Kalyan

Sep 22 '06 #1
9 5620
rkk said:
Hi,

I have written a generic mergesort program which is as below:
I took a long hard look at it, and got rid of many obvious bugs, which left
a not-so-obvious bug that I couldn't dislodge.

My best advice to you would be:

1) remove all casts - I guessed they were *all* wrong, and my guess was
correct
2) use void *, not void *[]
3) in Merge, use an unsigned char * to point at the base of the array
4) do your own pointer arithmetic properly (your code currently ignores the
problem of object sizes)
5) protect against malloc failure (returning, say, 0 if all went well and 1
if a memory allocation failure occurred)
6) write your comparison routine so that it doesn't need casts
7) choose better identifier names, names that reflect what the identifier
represents (e.g. you might want to use left, mid, and right, rather than p,
q, and r)

Once you have fixed all that up, you'll still have a bug. I couldn't find
that one, and wasn't heavily motivated to try. After applying all the
obvious fixes (see above), I got an output of

1 2 15 21 26 26 26

which is in some ways better and in some ways worse than your output.
Clearly, it has done some sorting - which is good! - but equally clearly it
has smeared one of the values across part of the array - which is not good.

So at least one bug remains. If you would like me to make my changes
available to you, just yell - but, as you can see, more work is required.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 22 '06 #2
BRG
Richard Heathfield wrote:

[snip]
Once you have fixed all that up, you'll still have a bug. I couldn't find
that one, and wasn't heavily motivated to try.
In addition to the issues you found, the convention on the end index for
an array partition seems suspect. In some places it appears that the
index for the last array element is being used while in other places it
seems that this top index refers to one element beyond the last element.

For example the line:

while( j <= r ) out[k++] = array[j++];

uses the array[r] element whereas the following line:

for (i = p; i < r; i++)

excludes this element.

It's quite possible that this is correct since I have not studied the
code in any detail. But it looks suspicious to me.

Brian Gladman
Sep 22 '06 #3
rkk schrieb:
Hi,

I have written a generic mergesort program which is as below:
---------------------------------------------------------
mergesort.h
-----------------------

void
MergeSort(void *array[],int p,int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB));
void
Merge(void *array[],int p,int q, int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB));
int
IntegerComp(con st void *keyA,const void *keyB);

mergesort.c
--------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mergesort. h"
void
MergeSort(void *array[],int p,int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB))
Note: If you have an array of void*, then elemSize == sizeof (void*).
You probably want either an array of generic pointers which you
sort (an "index array") or an array of elements which you sort directly.
I will go for the latter even though it is not very efficient for
large elemSize.
{
int q;
if(p < r) {
q = (p + r)/2;
MergeSort(array ,p,q,elemSize,C ompare);
MergeSort(array ,q + 1,r,elemSize,Co mpare);
This suggests that p and r are valid indices.
Merge(array,p,q ,r,elemSize,Com pare);
}
}

void
Merge(void *array[],int p,int q, int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB))
Same as above.
{
void **out = (void **)malloc(elemS ize * r);
No check whether this was successful.
You do not allocate the size you need which is
elemSize * (r- p + 1)

Note: One of the primary advantages of merge sort is that
you do not have to keep everything in memory. Allocating
a temp array leads that ad absurdum -- if a temp array is
allowed, then we can implement something more efficient...
int i,k,j;
i = k = p;
If you allocate only as much as you need, then k should start at 0.
j = q + 1;
while( i <= q && j <= r ) {
if( Compare( &array[i * elemSize],&array[j * elemSize] ) <= 0 ) {
You cannot calculate the address of the array members like this.
(unsigned char *)array + i * elemSize
is the correct way to do this.
out[k++] = array[i++];
} else {
out[k++] = array[j++];
}
}
while( i <= q ) out[k++] = array[i++];
while( j <= r ) out[k++] = array[j++];

for (i = p;i < r; i++) {
array[i] = out[i];
}
free(out);
}
int
IntegerComp(con st void *keyA,const void *keyB)
{
if( (const int *) keyA == (const int *) keyB ) return 0;
else if( (const int *) keyA < (const int *) keyB ) return -1;
else if( (const int *) keyA (const int *) keyB ) return 1;
}
----------------------------------------------
And the driver program is here:
test.c
---------
#include <stdio.h>
#include "mergesort. h"

int
main()
{
int idx,length;
int arr[] = { 2,21,1,48,15,31 ,26 };
length = sizeof arr/sizeof &arr[0];
sizeof arr / sizeof arr[0]
>
printf("Before sorting array:\n");
for (idx = 0;idx < length;idx++)
{
printf("%d ",arr[idx]);
}
printf("\n");

MergeSort(&arr, 0,length,sizeof (int),IntegerCo mp);
You have to pass "length - 1". If you write sizeof arr[0],
then you are on the safe side even if the type of arr changes.
>
printf("After sorting array:\n");
for (idx = 0;idx < length;idx++)
{
printf("%d ",arr[idx]);
}
printf("\n");
return 0;
}
----------------------------------------------------------
I compile the programs above as:

gcc -g -o mergesort mergesort.c test.c
gcc -std=c89 -pedantic -Wall -O test.c mergesort.c -o test

My changed version gives you some debug output; for this,
you need -DMY_DEBUG on the command line.

,-- mergesort.h --
#ifndef H_MERGE_SORT_H
#define H_MERGE_SORT_H

typedef int (*TCompareFcn) (const void *, const void *);

int
MergeSort (void *array,
int startIndex,
int endIndex,
int elemSize,
TCompareFcn Compare);

int
IntegerComp (const void *keyA,
const void *keyB);

#endif

`----
,-- test.c --
#include <stdio.h>
#include "mergesort. h"

int
main (void)
{
int idx, length;
int arr[] = { 2,21,1,48,15,31 ,26 };
length = sizeof arr / sizeof arr[0];

puts("Before sorting array:");
for (idx = 0; idx < length; idx++)
{
printf(" %d", arr[idx]);
}
putchar('\n');

if (!MergeSort(arr , 0, length - 1, sizeof arr[0], IntegerComp))
fputs("Merging not successful\n", stderr);

puts("After sorting array:");
for (idx = 0; idx < length; idx++)
{
printf(" %d", arr[idx]);
}
putchar('\n');
return 0;
}

`----
,-- mergesort.c --
#include "mergesort. h"

#include <string.h>
#include <stdlib.h>

#ifdef MY_DEBUG
# include <stdio.h>
# define DEBUG_PRINT(s) printf s
# define DEBUG_I_PRINT(s ) printf("%*s", indent, " "), DEBUG_PRINT(s)
static int indent = 0;
# define DEBUG_ENTER indent += 3
# define DEBUG_EXIT indent -= 3
#else
# define DEBUG_PRINT(s)
# define DEBUG_I_PRINT(s )
# define DEBUG_ENTER
# define DEBUG_EXIT
#endif

static int
Merge (void *array,
int p,
int q,
int r,
int elemSize,
TCompareFcn Compare);

int
MergeSort (void *array,
int startIndex,
int endIndex,
int elemSize,
TCompareFcn Compare)
{
if (startIndex < endIndex) {
int splitIndex;
DEBUG_ENTER;
splitIndex = (startIndex + endIndex) / 2;

DEBUG_I_PRINT(( "MergeSort: %d %d\n", startIndex, splitIndex));
if (!MergeSort(arr ay,startIndex,s plitIndex,elemS ize,Compare))
return 0;
DEBUG_I_PRINT(( "MergeSort: %d %d\n", splitIndex+1, endIndex));
if (!MergeSort(arr ay,splitIndex + 1,endIndex,elem Size,Compare))
return 0;

DEBUG_I_PRINT(( "Merge: %d %d %d\n", startIndex, splitIndex, endIndex));
if (!Merge(array,s tartIndex,split Index,endIndex, elemSize,Compar e))
return 0;
DEBUG_EXIT;
}
return 1;
}

static int
Merge (void *array,
int startIndex,
int splitIndex,
int endIndex,
int elemSize,
TCompareFcn Compare)
{
int numElems = endIndex - startIndex + 1;
unsigned char *pTemp, *pCurrTemp;
unsigned char *pArrBase = array;
int lowerCurr = startIndex;
int upperCurr = splitIndex + 1;
const unsigned char *pArrLower = pArrBase + lowerCurr*elemS ize;
const unsigned char *pArrUpper = pArrBase + upperCurr*elemS ize;

pTemp = malloc(elemSize * numElems);
if (NULL == pTemp)
return 0;
pCurrTemp = pTemp;

DEBUG_ENTER;
while (lowerCurr <= splitIndex && upperCurr <= endIndex) {
DEBUG_I_PRINT(( "[%d(%d) %d(%d) -", lowerCurr, *(int*)pArrLowe r,
upperCurr, *(int*)pArrUppe r));
if ((*Compare)(pAr rLower, pArrUpper) <= 0 ) {
DEBUG_PRINT(("% d]\n", lowerCurr));
memcpy(pCurrTem p, pArrLower, elemSize);
pArrLower += elemSize;
++lowerCurr;
} else {
DEBUG_PRINT(("% d]\n", upperCurr));
memcpy(pCurrTem p, pArrUpper, elemSize);
pArrUpper += elemSize;
++upperCurr;
}
pCurrTemp += elemSize;
}
while (lowerCurr <= splitIndex ) {
DEBUG_I_PRINT(( "[%d(%d)]\n", lowerCurr, *(int*)pArrLowe r));
memcpy(pCurrTem p, pArrLower, elemSize);
pArrLower += elemSize;
++lowerCurr;
pCurrTemp += elemSize;
}
while (upperCurr <= endIndex) {
DEBUG_I_PRINT(( "[%d(%d)]\n", upperCurr, *(int*)pArrUppe r));
memcpy(pCurrTem p, pArrUpper, elemSize);
pArrUpper += elemSize;
++upperCurr;
pCurrTemp += elemSize;
}

memcpy(pArrBase + startIndex*elem Size, pTemp, elemSize * numElems);

free(pTemp);
DEBUG_EXIT;

return 1;
}
int
IntegerComp(con st void *keyA, const void *keyB)
{
const int *pIntKeyA = keyA;
const int *pIntKeyB = keyB;

return (*pIntKeyA *pIntKeyB) - (*pIntKeyA < *pIntKeyB);
}

`----

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Sep 22 '06 #4
BRG said:

<snip>
For example the line:

while( j <= r ) out[k++] = array[j++];

uses the array[r] element whereas the following line:

for (i = p; i < r; i++)

excludes this element.
Ah, thank you, Brian. Good spot. Together with my other fixes, that is
sufficient that the OP's sample array is correctly sorted, as is a second
test array I tried.

All that remains is to see whether he is sufficiently interested in his own
problem to request me to post my fixes. :-)
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 22 '06 #5
Michael Mair wrote:
rkk schrieb:
>I have written a generic mergesort program which is as below:
.... snip ...
>
Note: One of the primary advantages of merge sort is that
you do not have to keep everything in memory. Allocating
a temp array leads that ad absurdum -- if a temp array is
allowed, then we can implement something more efficient...
Mergesort is primarily useful in dealing with linked lists or
monstrous files, where its stability and ability to handle
arbitrary length lists are very helpful.

--
Some informative links:
news:news.annou nce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html

--
Posted via a free Usenet account from http://www.teranews.com

Sep 23 '06 #6
rkk
Sorry for late response.

I do understand the mistakes I did in my version of program. Shortly I
will post my own corrected version.

Also Thanks to Michael for his mergesort code. It is really helpful.
Much appreciated.

One doubt I have is that to calculate the mem address of array why it
has to be casted to unsigned char * why cant char* instead? Sorry to
ask this very silly question here.

Many thanks for all of your help.

Regards
Kalyan

Richard Heathfield wrote:
BRG said:

<snip>
For example the line:

while( j <= r ) out[k++] = array[j++];

uses the array[r] element whereas the following line:

for (i = p; i < r; i++)

excludes this element.

Ah, thank you, Brian. Good spot. Together with my other fixes, that is
sufficient that the OP's sample array is correctly sorted, as is a second
test array I tried.

All that remains is to see whether he is sufficiently interested in his own
problem to request me to post my fixes. :-)
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 24 '06 #7
rkk
Michael, Many thanks for this piece of code.

Regards
Kalyan

Michael Mair wrote:
rkk schrieb:
Hi,

I have written a generic mergesort program which is as below:
---------------------------------------------------------
mergesort.h
-----------------------

void
MergeSort(void *array[],int p,int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB));
void
Merge(void *array[],int p,int q, int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB));
int
IntegerComp(con st void *keyA,const void *keyB);

mergesort.c
--------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mergesort. h"
void
MergeSort(void *array[],int p,int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB))

Note: If you have an array of void*, then elemSize == sizeof (void*).
You probably want either an array of generic pointers which you
sort (an "index array") or an array of elements which you sort directly.
I will go for the latter even though it is not very efficient for
large elemSize.
{
int q;
if(p < r) {
q = (p + r)/2;
MergeSort(array ,p,q,elemSize,C ompare);
MergeSort(array ,q + 1,r,elemSize,Co mpare);

This suggests that p and r are valid indices.
Merge(array,p,q ,r,elemSize,Com pare);
}
}

void
Merge(void *array[],int p,int q, int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB))

Same as above.
{
void **out = (void **)malloc(elemS ize * r);

No check whether this was successful.
You do not allocate the size you need which is
elemSize * (r- p + 1)

Note: One of the primary advantages of merge sort is that
you do not have to keep everything in memory. Allocating
a temp array leads that ad absurdum -- if a temp array is
allowed, then we can implement something more efficient...
int i,k,j;
i = k = p;

If you allocate only as much as you need, then k should start at 0.
j = q + 1;
while( i <= q && j <= r ) {
if( Compare( &array[i * elemSize],&array[j * elemSize] ) <= 0 ) {

You cannot calculate the address of the array members like this.
(unsigned char *)array + i * elemSize
is the correct way to do this.
out[k++] = array[i++];
} else {
out[k++] = array[j++];
}
}
while( i <= q ) out[k++] = array[i++];
while( j <= r ) out[k++] = array[j++];

for (i = p;i < r; i++) {
array[i] = out[i];
}
free(out);
}
int
IntegerComp(con st void *keyA,const void *keyB)
{
if( (const int *) keyA == (const int *) keyB ) return 0;
else if( (const int *) keyA < (const int *) keyB ) return -1;
else if( (const int *) keyA (const int *) keyB ) return 1;
}
----------------------------------------------
And the driver program is here:
test.c
---------
#include <stdio.h>
#include "mergesort. h"

int
main()
{
int idx,length;
int arr[] = { 2,21,1,48,15,31 ,26 };
length = sizeof arr/sizeof &arr[0];

sizeof arr / sizeof arr[0]

printf("Before sorting array:\n");
for (idx = 0;idx < length;idx++)
{
printf("%d ",arr[idx]);
}
printf("\n");

MergeSort(&arr, 0,length,sizeof (int),IntegerCo mp);

You have to pass "length - 1". If you write sizeof arr[0],
then you are on the safe side even if the type of arr changes.

printf("After sorting array:\n");
for (idx = 0;idx < length;idx++)
{
printf("%d ",arr[idx]);
}
printf("\n");
return 0;
}
----------------------------------------------------------
I compile the programs above as:

gcc -g -o mergesort mergesort.c test.c

gcc -std=c89 -pedantic -Wall -O test.c mergesort.c -o test

My changed version gives you some debug output; for this,
you need -DMY_DEBUG on the command line.

,-- mergesort.h --
#ifndef H_MERGE_SORT_H
#define H_MERGE_SORT_H

typedef int (*TCompareFcn) (const void *, const void *);

int
MergeSort (void *array,
int startIndex,
int endIndex,
int elemSize,
TCompareFcn Compare);

int
IntegerComp (const void *keyA,
const void *keyB);

#endif

`----
,-- test.c --
#include <stdio.h>
#include "mergesort. h"

int
main (void)
{
int idx, length;
int arr[] = { 2,21,1,48,15,31 ,26 };
length = sizeof arr / sizeof arr[0];

puts("Before sorting array:");
for (idx = 0; idx < length; idx++)
{
printf(" %d", arr[idx]);
}
putchar('\n');

if (!MergeSort(arr , 0, length - 1, sizeof arr[0], IntegerComp))
fputs("Merging not successful\n", stderr);

puts("After sorting array:");
for (idx = 0; idx < length; idx++)
{
printf(" %d", arr[idx]);
}
putchar('\n');
return 0;
}

`----
,-- mergesort.c --
#include "mergesort. h"

#include <string.h>
#include <stdlib.h>

#ifdef MY_DEBUG
# include <stdio.h>
# define DEBUG_PRINT(s) printf s
# define DEBUG_I_PRINT(s ) printf("%*s", indent, " "), DEBUG_PRINT(s)
static int indent = 0;
# define DEBUG_ENTER indent += 3
# define DEBUG_EXIT indent -= 3
#else
# define DEBUG_PRINT(s)
# define DEBUG_I_PRINT(s )
# define DEBUG_ENTER
# define DEBUG_EXIT
#endif

static int
Merge (void *array,
int p,
int q,
int r,
int elemSize,
TCompareFcn Compare);

int
MergeSort (void *array,
int startIndex,
int endIndex,
int elemSize,
TCompareFcn Compare)
{
if (startIndex < endIndex) {
int splitIndex;
DEBUG_ENTER;
splitIndex = (startIndex + endIndex) / 2;

DEBUG_I_PRINT(( "MergeSort: %d %d\n", startIndex, splitIndex));
if (!MergeSort(arr ay,startIndex,s plitIndex,elemS ize,Compare))
return 0;
DEBUG_I_PRINT(( "MergeSort: %d %d\n", splitIndex+1, endIndex));
if (!MergeSort(arr ay,splitIndex + 1,endIndex,elem Size,Compare))
return 0;

DEBUG_I_PRINT(( "Merge: %d %d %d\n", startIndex, splitIndex, endIndex));
if (!Merge(array,s tartIndex,split Index,endIndex, elemSize,Compar e))
return 0;
DEBUG_EXIT;
}
return 1;
}

static int
Merge (void *array,
int startIndex,
int splitIndex,
int endIndex,
int elemSize,
TCompareFcn Compare)
{
int numElems = endIndex - startIndex + 1;
unsigned char *pTemp, *pCurrTemp;
unsigned char *pArrBase = array;
int lowerCurr = startIndex;
int upperCurr = splitIndex + 1;
const unsigned char *pArrLower = pArrBase + lowerCurr*elemS ize;
const unsigned char *pArrUpper = pArrBase + upperCurr*elemS ize;

pTemp = malloc(elemSize * numElems);
if (NULL == pTemp)
return 0;
pCurrTemp = pTemp;

DEBUG_ENTER;
while (lowerCurr <= splitIndex && upperCurr <= endIndex) {
DEBUG_I_PRINT(( "[%d(%d) %d(%d) -", lowerCurr, *(int*)pArrLowe r,
upperCurr, *(int*)pArrUppe r));
if ((*Compare)(pAr rLower, pArrUpper) <= 0 ) {
DEBUG_PRINT(("% d]\n", lowerCurr));
memcpy(pCurrTem p, pArrLower, elemSize);
pArrLower += elemSize;
++lowerCurr;
} else {
DEBUG_PRINT(("% d]\n", upperCurr));
memcpy(pCurrTem p, pArrUpper, elemSize);
pArrUpper += elemSize;
++upperCurr;
}
pCurrTemp += elemSize;
}
while (lowerCurr <= splitIndex ) {
DEBUG_I_PRINT(( "[%d(%d)]\n", lowerCurr, *(int*)pArrLowe r));
memcpy(pCurrTem p, pArrLower, elemSize);
pArrLower += elemSize;
++lowerCurr;
pCurrTemp += elemSize;
}
while (upperCurr <= endIndex) {
DEBUG_I_PRINT(( "[%d(%d)]\n", upperCurr, *(int*)pArrUppe r));
memcpy(pCurrTem p, pArrUpper, elemSize);
pArrUpper += elemSize;
++upperCurr;
pCurrTemp += elemSize;
}

memcpy(pArrBase + startIndex*elem Size, pTemp, elemSize * numElems);

free(pTemp);
DEBUG_EXIT;

return 1;
}
int
IntegerComp(con st void *keyA, const void *keyB)
{
const int *pIntKeyA = keyA;
const int *pIntKeyB = keyB;

return (*pIntKeyA *pIntKeyB) - (*pIntKeyA < *pIntKeyB);
}

`----

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Sep 24 '06 #8
Please do not top-post.
Your reply belongs below (or interspersed with) the text you
are replying to; you of course can and should snip whatever
you find not useful for the parts you want to discuss further.

rkk schrieb:
Richard Heathfield wrote:
>>BRG said:
<snip: inconsistent use of the top index (included/excluded)
>>
Ah, thank you, Brian. Good spot. Together with my other fixes, that is
sufficient that the OP's sample array is correctly sorted, as is a second
test array I tried.

All that remains is to see whether he is sufficiently interested in his own
problem to request me to post my fixes. :-)

Sorry for late response.

I do understand the mistakes I did in my version of program. Shortly I
will post my own corrected version.

Also Thanks to Michael for his mergesort code. It is really helpful.
Much appreciated.
I am happy to hear that :-)
Note that this was only an example implementation of one of the
two possible solutions and not the one I would actually implement.

One doubt I have is that to calculate the mem address of array why it
has to be casted to unsigned char * why cant char* instead? Sorry to
ask this very silly question here.
Not a silly question at all.

Even though void * has the same representation and alignment
requirements as a pointer to any of the three types of char,
you cannot do pointer arithmetic with it.
[Three types of char? char is special in that there is a difference
between signed char and "plain" char which is a type distinct from
both signed char and unsigned char but has the characteristics of
one of these.]
unsigned char * is the only type with which you can guaranteedly
access the representation (i.e. the underlying bit pattern) of any
object:
myType foo;
void *pFoo = &foo;
unsigned char *bar = pFoo;
int i;

/* assign value to foo */
....

for (i = 0; i < sizeof foo; ++i) {
printf("%x\t", (unsigned int) bar[i]);
}
putchar('\n');
will give you the bytes of foo.
Neither char * nor signed char * guaranteedly can give you that.
Thus, you use "char" for characters and "unsigned char" if you
mean bytes and want to calculate addresses.

The comp.lang.c FAQ tells you a little bit more about that:
http://c-faq.com
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Sep 24 '06 #9
rkk wrote:
>
.... snip ...
>
One doubt I have is that to calculate the mem address of array why
it has to be casted to unsigned char * why cant char* instead?
Sorry to ask this very silly question here.
Please don't top-post. Your answer belongs after, or possibly
intermixed with, the material you quote, after snipping. See the
links in my sig. below.

You cast to unsigned char because your system may define char as
either signed or unsigned. Without the cast the code is not
portable. Many routines (e.g. toupper() etc.) require unsigned
chars.

--
Some informative links:
<news:news.anno unce.newusers
<http://www.geocities.c om/nnqweb/>
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html >
<http://www.netmeister. org/news/learn2quote.htm l>
<http://cfaj.freeshell. org/google/>
Sep 24 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
2517
by: Tim Mohler | last post by:
All - I have a script that provides a web page interface to various system utilities. Once the user has selected the utility and input various parameters, it calls itself with a different method and input value, for instance ping. During the initial call, the output is not buffered, but on the second call, the actually executes the utility, output is buffered until the command completes.
3
10443
by: Mark A Framness | last post by:
Greetings, I am working on a project and we need to write a conversion script to initialize a new field on a table. The number of records on this table is on the order of millions so routine selection and update takes a long time. I am tasked with writing a pl/sql proc that utilizes array processing to update the column.
3
4601
by: Kevin King | last post by:
I have a question about an assignment I have. I need to count the number of comparisons in my merge sort. I know that the function is roughly nlog(n), but I am definately coming up with too many comparisons. It seems to me like I should just use a single counter in the merge function's 'if' statement, but this can't be right because an array of 50 takes about 100 comparisons this way. If anyone has any suggestions I would greatly...
14
1772
by: Michael R. Copeland | last post by:
I'm writing an application that requires an "intelligent merge" of 2 files. That is, equal data has a "preferred source" that I want to write out. What I have works, I believe, but it seems horribly cumbersome (having to set the input variables to ""...). Is there a better way? TIA while ((!feof(wf3)) || (!feof(wf1))) { if (!feof(wf1)) {
48
4473
by: Alex Chudnovsky | last post by:
I have come across with what appears to be a significant performance bug in ..NET 2.0 ArrayList.Sort method when compared with Array.Sort on the same data. Same data on the same CPU gets sorted a lot faster with both methods using .NET 1.1, that's why I am pretty sure its a (rather serious) bug. Below you can find C# test case that should allow you to reproduce this error, to run it you will need to put 2 data files into current directory...
5
3203
by: tienlx | last post by:
Hi all, I want to sort an array of struct _line: .... typedef struct _line { int x1; int x2; } line;
2
2883
by: mqueene7 | last post by:
below is my code for my merge sort but I can't get it to sort properly. I am trying generate random numbers based on input from the user and then sort those random numbers. Can you tell me what I am doing wrong? void merge(int,int,int); void merge_sort(int low, int high) { int mid, temp; if (low==high) return; if (low+1==high)
3
3963
by: Michel Esber | last post by:
Hi all, DB2 V8 LUW FP 15 There is a table T (ID varchar (24), ABC timestamp). ID is PK. Our application needs to frequently update T with a new value for ABC. update T set ABC=? where ID = ?
3
5189
by: aRTx | last post by:
I have try a couple of time but does not work for me My files everytime are sortet by NAME. I want to Sort my files by Date-desc. Can anyone help me to do it? The Script <? /* ORIGJINALI
0
8707
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9314
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9174
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9015
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6634
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4464
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4725
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3158
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2520
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.