views:

205

answers:

4

I want to pass an array of arbitrary struct pointers and a comparison function to a generic sorting algorithm. Is this possible in C?

The goooeys of the structs would only be accessed within the comparison function, the sorting function would only need to call the comparison function and swap pointers, but I can't figure out how to declare it.

function sorter( struct arbitrary ** Array, int Length, int cmp(struct node * a, struct node * b))
{
    for (int i=0; i<Length;i++){
        if cmp(Array[i],Array[i+1]){
            swap(Array[i],Array[i+1]
       }
    }
}
A: 

Maybe you need to pass just void pointers?

function sorter(void ** Array, int Length, int cmp(void * a, void * b))
Kinopiko
+3  A: 

You can declare the function as:

void sorter(void** the_array, size_t array_length, int (*comparison_function)(void*, void*));

Inside of the comparison function, you will then need to cast the two pointers being compared to pointers to whatever struct type the comparison function compares.

James McNellis
You mean "you *don't* have to derefence the pointer", don't you? But the OP seems to know that already.
AndreyT
Thanks, I didn't know I could use void pointers like that.
ABentSpoon
@AndreyT: That's what happens when I'm up late on StackOverflow; sorry for the confusion. @ABentSpoon: You're welcome.
James McNellis
A: 

It's always possible in C simply because you can convert every pointer to a void*. But, if you want to be able to convert that back to a pointer to an arbitrary structure, you'll need some sort of type identification.

You could do that by using a function specific to the type (if the things you are comparing are the same), or encode the type into the structure somehow. This can be done by having an extra field in the structure or by changing the cmp() function itself to take a type identifier.

But you should be aware that C already has a qsort() function that's usually reasonably efficient (although there's nothing in the standard that dictates what algorithm it uses - it could use bubble sort and still be conforming). Unless you're implementing one for homework, or have a different algorithm in mind, tou should probably just use that.

Your algorithm, as it stands, looks like the inner loop of a bubble sort and, as such, won't actually sort correctly. Bubble sort consists of two nested loops and is generally only suitable for small data sets or those with specific characteristics (such as mostly sorted already).

paxdiablo
+1  A: 

Actually, this function already exists... it is called qsort. See some documentation here. It's also more efficient than your implementation, which is O(n^2).

rlbond
Actually, that implementation is O(n) which would be pretty good for a sort routine, except for the fact that it doesn't sort :-)
paxdiablo
Actually, mine is O(n), but it only sorts nearly sorted arrays :). However, thanks. I'll definitely be taking advantage of this.
ABentSpoon
There's usually mergesort() too on libc for the case of nearly sorted arrays. Remember it consumes a bit more memory than qsort, though.
alecco
Technically, you can't say what qsort will consume since the standard doesn't specify an algorithm. It's not necessarily quicksort.
paxdiablo