Bubble Sort using pointers to function

戏子无情 提交于 2019-12-08 14:03:21

问题


I'm trying to implement a bubble sort in c by using pointers to function but does not work. Can anyone help me? Here is the code:

#include <stdio.h>
#include <stdlib.h>

void bubbleSort(void** base, size_t length, int (*compar)(const void*, const void*));

int main(int argc, char* argv[]) {
    int cmp(const void*, const void*);
    int vet[] = {1, 2, 5, 7, 6, 1, 3, 2, 9, 15, 14, 20};
    bubbleSort((void**) &vet, sizeof(vet)/sizeof(vet[0]), cmp);
    int i;
    for (i = 0; i < sizeof(vet)/sizeof(vet[0]); i++) {
        printf("%d\n", vet[i]);
    }
    return 0;
}

int cmp(const void* x, const void* y) {
    return **((int* const*) x) - **((int* const*) y);
}

void bubbleSort(void** base, size_t length, int (*compar)(const void*, const void*)) {
     int i, j;
     void swap(void*, void*);
     for (i = 0; i < length; i++) {
       for (j = 1; j < length; j++) {
           if ((*compar)(base[i], base[i]) < 0) {
               swap(base[i], base [j]);
           }
       }
     }
}

void swap(void* a, void* b) {
     void* tmp = a;
     a = b;
     b = tmp;
}

The output is the same vector without sorting. (Sorry for my English)


回答1:


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

int cmp(const void *x, const void *y){
    int a = *(const int *)x;
    int b = *(const int *)y;
    return a < b ? -1 : (a > b);
}

void swap(void *a, void *b, size_t type_size) {
    void *tmp = malloc(type_size);
    memcpy(tmp, a, type_size);
    memcpy(a,   b, type_size);
    memcpy(b, tmp, type_size);
    free(tmp);
}

void bubbleSort(void *base, size_t length, size_t type_size, int (*compar)(const void*, const void*)) {
    int i, j;
    for (i = 0; i < length - 1; ++i) {
        for (j = i+1; j < length; ++j){
            char *data_i = (char*)base + type_size * i;
            char *data_j = (char*)base + type_size * j;
            if(compar(data_i, data_j) > 0)
                swap(data_i, data_j, type_size);
        }
    }
}

int main() {
    int vet[] = {1, 2, 5, 7, 6, 1, 3, 2, 9, 15, 14, 20};
    bubbleSort(vet, sizeof(vet)/sizeof(*vet), sizeof(*vet), cmp);
    int i;
    for (i = 0; i < sizeof(vet)/sizeof(*vet); i++) {
        printf("%d\n", vet[i]);
    }
    return 0;
}



回答2:


When I ran the above code on my machine, I was getting a SIGSEGV. Then I found that there are many errors in your code.

Firstly, your swap function actually does nothing! You are passing two pointers to the array elements to that function. You are merely swapping the addresses to which these were pointing previously. Its quite useless. It can be written in many different ways. I prefer the following:

void swap(void* a, void* b) {
 //get the int pointers...
 int* t_a = (int*)a;
 int* t_b = (int*)b;

//now change the values in them...
 int tmp = *t_a;
 *t_a = *t_b;
 *t_b = tmp;

}

The reason I casted them first to int is that its meaningless to assign a value to a void*.

Coming to the bubbleSort code, what do you think base[i] refers to in your code? It isn't the value of the ith element in the array. It being a double-pointer, base[i] actually refers to the ith pointer pointing to some other array.

Since there is only a single array here, so base[0] is the only valid address which we have. If you try to refer other pointers, then its a SIGSEGV, which I anticipated way before running the code.

What you need to do is, first get a pointer pointing to the first element of the array.(say ptr). Now ptr is nothing but our initial array. Then use this.

void bubbleSort(void** base, size_t length, int (*compar)(const void*, const void*)) {
     int i, j;
     int *ptr = &(*base);
     for (i = 0; i < length; i++) {
       for (j = 1; j < length; j++) {
           if ((*compar)(&ptr[i], &ptr[j]) < 0) {
               swap(&ptr[i], &ptr[j]);
           }
       }
     }
}

Hope this helps...



来源:https://stackoverflow.com/questions/21299217/bubble-sort-using-pointers-to-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!