【问题标题】:Bubble Sort using pointers to function使用函数指针进行冒泡排序
【发布时间】:2014-01-23 04:12:49
【问题描述】:

我正在尝试通过使用指向函数的指针在 c 中实现冒泡排序,但它不起作用。谁能帮我?代码如下:

#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;
}

输出是相同的向量,没有排序。 (对不起我的英语)

【问题讨论】:

  • 使用你的调试器,卢克。

标签: c pointers function-pointers void-pointers


【解决方案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】:

    当我在我的机器上运行上述代码时,我得到了一个SIGSEGV。然后我发现你的代码有很多错误。

    首先,您的swap 函数实际上什么都不做!您正在将两个指向数组元素的指针传递给该函数。您只是在交换这些以前指向的地址。它完全没用。它可以用许多不同的方式编写。我更喜欢以下内容:

    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;
    

    }

    我首先将它们强制转换为 int 的原因是为 void* 赋值是没有意义的。

    谈到bubbleSort 代码,您认为base[i] 在您的代码中指的是什么?它不是数组中 ith 元素的值。它是一个双指针,base[i] 实际上是指指向其他数组的ith 指针。

    由于这里只有一个数组,所以base[0] 是我们拥有的唯一有效地址。如果您尝试引用其他指针,则它是 SIGSEGV,这是我在运行代码之前所预料到的。

    你需要做的是,首先得到一个指向数组第一个元素的指针。(比如ptr)。现在ptr 只是我们的初始数组。然后用这个。

    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]);
               }
           }
         }
    }
    

    希望这会有所帮助...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-25
      • 2019-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多