C中的通用插入排序

时间:2016-01-24 09:39:35

标签: c sorting generics insertion

我在C中编写了一个通用插入排序,它工作得非常好。

但是,在我的插入排序功能上,它得到void** arr, 并且在它的签名上得到void* arr,否则,它不起作用。

为什么会这样? 我们是否有其他方法可以将插入排序编码为通用?

完整代码在这里:

#include <stdio.h>
#include <malloc.h>
#define SIZE 10
int cmp(void* elm1, void* elm2);
void insertionSort(void* arr, int size);

int main()
{
    int arr[] = {5, 8, 2, 3, 15, 7, 4, 9, 20, 13};
    int arr2[] =  {1};
    int i;
    for (i = 0; i < SIZE; i++)
        printf("%d ", arr[i]);
    printf("\n");
    insertionSort(&arr, SIZE);
    for (i = 0; i < SIZE; i++)
        printf("%d ", arr[i]);
    return 0;
}

void insertionSort(void** arr, int size)
{
    int i = 1;
    int j;
    void* temp;
    while (i < size)
    {
        if (cmp(arr[i], arr[i-1]) == -1)
        {
            temp = arr[i];
            j = i - 1;
            while (j >= 0 && cmp(arr[j], temp) == 1)
            {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = temp;
        }
        i++;
    }
}

int cmp(void* elm1, void* elm2)
{
    if ((int)elm1 == (int)elm2)
        return 0;
    else if ((int)elm1 > (int)elm2)
        return 1;
    else 
        return -1;
}

2 个答案:

答案 0 :(得分:1)

由于存在多个问题,因此未定义代码。它恰好起作用,因为在你的系统上,指针的大小与类型(deftest async-test (testing "Testing some core.async functionality." (async done (go (is (= (<! (go "val")) "val1")) (done))))) 的大小相同。

您的代码不会在没有警告的情况下编译(如果您启用它们)。 insertSort函数和它的原型必须具有相同的类型。

您应该将函数定义中的类型更改为

int

然后将指针arr转换为适当的类型。由于这是一个通用的排序,如qsort(),唯一现实的选择是转换为void insertionSort(void* arr, int size) 。这意味着您还必须将类型的大小传递给函数,因此指针可以正确递增。这将要求您彻底改变功能。

因此,函数原型应该与qsort完全相同:

char*

答案 1 :(得分:0)

问题是integers不是指针,因此您的测试数组的类型为*intint[]。但是在你的函数中,你不知道这一点,并且你试图让你的代码使用指针。所以你期待* void[]。如果您将temp变量更改为int,则签名中不需要**。同样,如果你想保持“通用”(当你调用时),你需要一个*int的数组。

基本上,在C语言中,你不能为主要类型和指针编写一个开箱即用的函数。你需要一些技巧。看看this stackoverflow,也许会有所帮助。