[英]Why is an extra element being added to my void** array when I use merge-sort?
当我使用mergeSort
对我的void**
数组进行排序(此数组包含指向整数的void*
指针)时,似乎会向该数组添加一个额外的1
(一个新元素)。 我几乎可以肯定问题出在mergeSort
或merge
,因为在调用mergeSort
之前打印我的void**
数组时,数据是正确的(只是未排序)。 这是代码。
#define SIZE 10
void mergeSort(void**, int, int);
void merge(void**, int, int, int);
int compare(void*, void*);
int main(void) {
int array[SIZE] = { 5, 6, 3, 2, 5, 6, 7, 4, 9, 3 };
void *voidArray[SIZE];
int query = 1;
void *queryPointer = &query;
for (int j = 0; j < SIZE; j++) {
voidArray[j] = &array[j];
}
printArray(voidArray);
mergeSort(voidArray, 0, SIZE);
printArray(voidArray);
result = binarySearch(voidArray, 0, SIZE, queryPointer);
if (result == -1) {
puts("Query not found.");
return(0);
}
printf("Query found at index %d.\n", result);
return(0);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void mergeSort(void **array, int head, int tail) {
if (head < tail) {
int middle = (head + ((tail - head) / 2));
mergeSort(array, head, middle);
mergeSort(array, (middle + 1), tail);
merge(array, head, middle, tail);
}
}
void merge(void **array, int head, int middle, int tail) {
int headLength = (middle - head + 1);
int tailLength = (tail - middle);
void *headSide[headLength];
void *tailSide[tailLength];
for (int i = 0; i < headLength; i++) {
headSide[i] = array[head + i];
}
for (int j = 0; j < tailLength; j++) {
tailSide[j] = array[middle + 1 + j];
}
int k = head;
int l = 0;
int m = 0;
while (l < headLength && m < tailLength) {
if (compare(headSide[l], tailSide[m]) == -1) {
array[k] = headSide[l];
l++;
} else {
array[k] = tailSide[m];
m++;
}
k++;
}
while (l < headLength) {
array[k] = headSide[l];
l++;
k++;
}
while (m < tailLength) {
array[k] = tailSide[m];
m++;
k++;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int compare(void *index, void *query) {
if (*((int *)index) == *((int *)query)) {
return (0);
}
if (*((int*)index) > *((int*)query)) {
return (1);
}
return (-1);
}
输出应具有未排序的数组,已排序的数组以及是否找到查询。 未排序的数组中没有1
,但排序后的数组中有1
; 同样,排序结果中缺少数字9
(有趣的是,如果我对9
执行二进制搜索,它将告诉我在索引10
处找到9
)。
示例输出(对于一个查询1
):
5 6 3 2 5 6 7 4 9 3
1 2 3 3 4 5 5 6 6 7
在索引0
找到查询。
检查您的数组下标。
int tailLength = (tail - middle)
tail是数组的大小,我认为tailLength不正确。
headSide[i] = array[head + i];
headSide[i]
void
而array[head + i]
void*
margeSort
和merge
的参数有些混乱。 传递范围中最后一个元素的索引在C语言中不是惯用的。在范围结束之后传递元素的索引要简单得多,这与传递0
和SIZE
int main()
: mergeSort(voidArray, 0, SIZE);
和result = binarySearch(voidArray, 0, SIZE, queryPointer);
这是此API的修改版本:
void mergeSort(void **array, int head, int tail) {
if (tail - head > 1) {
int middle = head + (tail - head) / 2);
mergeSort(array, head, middle);
mergeSort(array, middle, tail);
merge(array, head, middle, tail);
}
}
void merge(void **array, int head, int middle, int tail) {
int headLength = middle - head;
int tailLength = tail - middle;
void *headSide[headLength];
void *tailSide[tailLength];
for (int i = 0; i < headLength; i++) {
headSide[i] = array[head + i];
}
for (int j = 0; j < tailLength; j++) {
tailSide[j] = array[middle + j];
}
int k = head;
int l = 0;
int m = 0;
while (l < headLength && m < tailLength) {
if (compare(headSide[l], tailSide[m]) <= 0) {
array[k++] = headSide[l++];
} else {
array[k++] = tailSide[m++];
}
}
while (l < headLength) {
array[k++] = headSide[l++];
}
while (m < tailLength) {
array[k++] = tailSide[m++];
}
}
但是请注意,为大型阵列分配带有自动存储空间的临时数组headSide
和tailSide
(又名栈上 )是有风险的。 此外,不必将右半部分的元素保存到tailSide
因为在将元素复制到最终位置之前不会将其覆盖。 这是merge
一个简单版本:
void merge(void **array, int head, int middle, int tail) {
int headLength = middle - head;
void *headSide[headLength];
for (int i = 0; i < headLength; i++) {
headSide[i] = array[head + i];
}
int k = head;
int l = 0;
while (l < headLength && middle < tail) {
if (compare(headSide[l], array[middle]) <= 0) {
array[k++] = headSide[l++];
} else {
array[k++] = array[middle++];
}
}
while (l < headLength) {
array[k++] = headSide[l++];
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.