C 通用插入排序可以';t排序浮点数组

C 通用插入排序可以';t排序浮点数组,c,C,我已经编写了插入排序算法的通用版本。它可以处理int和char,但不能对浮点数进行排序。我想不出来。它是否与内存中浮点数的表示或其他内容有关 这是我的密码: void insertion_sort(void *array, int elemSize, int arrSize){ for(int i = 0;i < arrSize;i++){ for(int j = 1;j < arrSize;j++){ void *elem1 = (c

我已经编写了插入排序算法的通用版本。它可以处理int和char,但不能对浮点数进行排序。我想不出来。它是否与内存中浮点数的表示或其他内容有关

这是我的密码:

void insertion_sort(void *array, int elemSize, int arrSize){
    for(int i = 0;i < arrSize;i++){
        for(int j = 1;j < arrSize;j++){
            void *elem1 = (char *) array + ((j-1) * elemSize); 
            void *elem2 = (char *) array + (j * elemSize);
            if(memcmp(elem2,elem1,elemSize) < 0){
                void *temp = malloc(sizeof(elemSize));
                memcpy(temp,elem1,elemSize);
                memcpy(elem1,elem2,elemSize);
                memcpy(elem2,temp,elemSize);
                free(temp);
            }
        }
    }
}
编辑:
此代码也不适用于int或char。查看我在这里编写的另一个版本[link]:

编写此函数的更好方法是为int、char和float提供一个比较器函数,如下所示:

void insertion_sort(void *array, int elemSize, int arrSize, int (*cmp)(const void *,const void *)){
    void *temp = malloc(sizeof(elemSize));
    for(int i = 0;i < arrSize;i++){
        for(int j = 1;j < arrSize;j++){
            void *elem1 = (char *) array + ((j-1) * elemSize); 
            void *elem2 = (char *) array + (j * elemSize);
            if(cmp(elem2,elem1)){

                memcpy(temp,elem1,elemSize);
                memcpy(elem1,elem2,elemSize);
                memcpy(elem2,temp,elemSize);
            }
        }
    }
    free(temp);
}
插入排序(void*arr,int elemSize,int arrSize,int(*cmp)(常数 无效*,常数无效*)

并使用以下命令更改if条件:

if(cmp(elem2,elem1))

假设cmp在elem2时返回1

此外,temp变量应在for循环外部声明,并在末尾释放

插入\u排序在上述修改后应如下所示:

void insertion_sort(void *array, int elemSize, int arrSize, int (*cmp)(const void *,const void *)){
    void *temp = malloc(sizeof(elemSize));
    for(int i = 0;i < arrSize;i++){
        for(int j = 1;j < arrSize;j++){
            void *elem1 = (char *) array + ((j-1) * elemSize); 
            void *elem2 = (char *) array + (j * elemSize);
            if(cmp(elem2,elem1)){

                memcpy(temp,elem1,elemSize);
                memcpy(elem1,elem2,elemSize);
                memcpy(elem2,temp,elemSize);
            }
        }
    }
    free(temp);
}
void插入\u排序(void*数组,int elemSize,int arrSize,int(*cmp)(常量void*,常量void*)){
void*temp=malloc(sizeof(elemSize));
对于(int i=0;i
编写此函数的更好方法是为int、char和float提供一个比较器函数,如下所示:

void insertion_sort(void *array, int elemSize, int arrSize, int (*cmp)(const void *,const void *)){
    void *temp = malloc(sizeof(elemSize));
    for(int i = 0;i < arrSize;i++){
        for(int j = 1;j < arrSize;j++){
            void *elem1 = (char *) array + ((j-1) * elemSize); 
            void *elem2 = (char *) array + (j * elemSize);
            if(cmp(elem2,elem1)){

                memcpy(temp,elem1,elemSize);
                memcpy(elem1,elem2,elemSize);
                memcpy(elem2,temp,elemSize);
            }
        }
    }
    free(temp);
}
插入排序(void*arr,int elemSize,int arrSize,int(*cmp)(常数 无效*,常数无效*)

并使用以下命令更改if条件:

if(cmp(elem2,elem1))

假设cmp在elem2时返回1

此外,temp变量应在for循环外部声明,并在末尾释放

插入\u排序在上述修改后应如下所示:

void insertion_sort(void *array, int elemSize, int arrSize, int (*cmp)(const void *,const void *)){
    void *temp = malloc(sizeof(elemSize));
    for(int i = 0;i < arrSize;i++){
        for(int j = 1;j < arrSize;j++){
            void *elem1 = (char *) array + ((j-1) * elemSize); 
            void *elem2 = (char *) array + (j * elemSize);
            if(cmp(elem2,elem1)){

                memcpy(temp,elem1,elemSize);
                memcpy(elem1,elem2,elemSize);
                memcpy(elem2,temp,elemSize);
            }
        }
    }
    free(temp);
}
void插入\u排序(void*数组,int elemSize,int arrSize,int(*cmp)(常量void*,常量void*)){
void*temp=malloc(sizeof(elemSize));
对于(int i=0;i
虽然OP是朝着正确方向迈出的一步,但仍有一些问题需要解决

例如,这一行:

void *temp = malloc(sizeof(elemSize));
//                  ^^^^^^^  
如果数组的元素不是
int
s(类型为
elemSize
),将分配错误的字节数

已发布代码段中的条件

if (memcmp(elem2, elem1, elemSize) < 0) {
请注意,此自定义点不仅可以用于为不同类型概括排序函数,还可以用于排序方向(升序或降序)

一个小细节(不是错误,只是效率低下)是内部循环执行次数太多(总是从1到
arrSize
),对于O(n2)算法没有太大区别,但它们仍然是所需时间的两倍。该函数的修改版本如下所示

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

void insertion_sort(size_t array_size, void *array,
                    size_t elem_size,
                    cmp_fn cmp)
{
    void *buf = malloc(elem_size);
    //                 ^^^^^^^^^
    for(size_t i = 1; i < array_size; ++i)
    {
        for(size_t j = i; j > 0;)
        { //           ^^^^^^^^^  
            void *b = (char *) array + (j * elem_size);
            void *a = (char *) array + (--j * elem_size);
            //                          ^^^
            if(cmp(a, b) == 1)
            {
                memcpy(buf, a, elem_size);
                memcpy(a, b, elem_size);
                memcpy(b, buf, elem_size);
            }
        }
    }
    free(buf);
}
typedef int(cmp_fn)(无效常数*,无效常数*);
无效插入\u排序(大小\u t数组\u大小,无效*数组,
大小元素大小,
cmp_fn cmp)
{
void*buf=malloc(元素尺寸);
//                 ^^^^^^^^^
对于(大小i=1;i<数组大小;++i)
{
对于(尺寸j=i;j>0;)
{ //           ^^^^^^^^^  
void*b=(char*)数组+(j*元素大小);
void*a=(char*)数组+(-j*元素大小);
//                          ^^^
if(cmp(a,b)==1)
{
memcpy(buf、a、elem_尺寸);
memcpy(a、b、元素大小);
memcpy(b、buf、元素大小);
}
}
}
免费(buf);
}
编辑

添加到问题的链接还导致尝试编写通用打印函数(注释):

void printArr(void*arr,int size,int elemSize){
对于(int i=0;i
除了类型不匹配之外,使用
elemSize
来确定数组的类型不是一个好主意,至少不是很好的移植性。例如,虽然一个体系结构的
sizeof(int)
等于
sizeof(char)
可能并不常见,但现在非常常见的是
sizeof(int)
等于
sizeof(float)
并且几乎可以肯定
sizeof(float)
小于
sizeof(double)
。这也无法区分
int
unsigned int
,但将使用相同的格式说明符

作为练习,实现像sort一样的通用打印函数可能会很有趣,它将指针传递给负责以正确方式打印元素的函数

值得注意的是,这种实现泛化的方法需要程序员非常小心,尤其是在