我正在尝试以与C的qsort函数相同的方式编写自己的Mergesort函数。如果我为一系列已知项目编写MergeSort,我就不会有问题,但是因为我不知道它们会是什么,所以它会让我失去一个循环。
我教授给出的规范不希望我使用单独的函数进行合并,所以我在Mergesort函数本身内编写了该实现。这意味着我将拥有qsort()所拥有的相同信息:
void* base
- 指向要排序的数组的第一个元素的指针size_t nel
- 数组中元素的数量size_t width
- 每个元素的大小int (*compar)( const void*, const void* )
- 一个告诉您如何比较每个元素的函数我遇到的问题是Merge部分。我看到的每个实现都使用临时数组来存储项目,同时对它们进行排序。我不习惯使用void指针,我发现的最大障碍是移动并将值分配给数组。如何在base
指向的数组中找到第二个索引处的值?如何将该数组中的值分配给临时数组?我该如何创建那个临时数组?
如果我将void指针转换为char,并将它们按宽度递增,它会工作吗?不过,我不确定作业是如何运作的。
答案 0 :(得分:3)
如何在base指向的数组中找到第二个索引处的值?
使用(char *)base + (width*i)
。这将为您提供第i个元素的地址。
如何将该数组中的值分配给临时数组?
您只需复制数据即可。 for (int n=0;n<width;n++) { //copy one byte from }
我如何创建临时数组?
类似的东西:
c - void* tempArray = malloc(width*elementsNeeded);
c ++ - void* tempArray = (void*) (new char[width*elementsNeeded]);
修改强>
为了进一步解释复制数据,您需要执行以下操作:
for (int n=0;n<width;n++) {
adressTo[n] = addressFrom[n];
}
// This will copy the contents of pointer addressFrom to addressTo.
答案 1 :(得分:2)
如何在base指向的数组中的第二个索引处找到该值?如果我将void指针转换为char,并将它们按宽度递增,它会工作吗?
是的,没错。 char的大小由标准定义为1,因此根据定义,您给出的“宽度”是字符中每个元素的大小。所以你可以找到如下地址:
void *second_element_ptr = ((char*)base) + width;
你找不到值,因为你不知道它的类型,所以你无法理解它占用的内存。但是没关系,使用这个接口对C中的对象进行排序,你不需要知道它们的值:你需要指向它们的指针,你可以将它们传递给比较器函数,并且你需要能够复制对象。
我如何将该数组中的值分配给临时数组?
char temporary_array[width]; // this is a C99 VLA, you might want to
// allocate the array differently
memcpy(temporary_array, second_element_ptr, width);
我如何创建该临时数组?
哦,我想我错误地接受了这些问题。对于包含单个元素的小数组,您可以在VLA上冒险。或者您可以按如下方式使用malloc:
// an array half the size of the input
// using char*, since unlike void* we can do arithmetic on it
char *big_temp_array = malloc(width * (nel + 1)/2);
顺便说一句,gcc支持void*
上的算术作为编译器扩展,将其视为char*
上的算术。由您决定是否可以/将使用它。