C语言中的合并排序错误
我想实现合并排序,即使我正在学习的类不需要它 下面是我的代码,我留下了一些printf函数来演示这个bug 该程序似乎可以工作,但当我在递归中进行最后几次合并时,它开始超出数组的参数范围,并开始比较垃圾值。它之所以有效,是因为这些值都是正值,但如果其中一个值是负值,它会将值存储在数组中 我试图找到这个bug,我所能看到的最好的bug与关系运算符有关,但我找不到修复方法 如果方向正确,我们将不胜感激C语言中的合并排序错误,c,mergesort,C,Mergesort,我想实现合并排序,即使我正在学习的类不需要它 下面是我的代码,我留下了一些printf函数来演示这个bug 该程序似乎可以工作,但当我在递归中进行最后几次合并时,它开始超出数组的参数范围,并开始比较垃圾值。它之所以有效,是因为这些值都是正值,但如果其中一个值是负值,它会将值存储在数组中 我试图找到这个bug,我所能看到的最好的bug与关系运算符有关,但我找不到修复方法 如果方向正确,我们将不胜感激 #include <stdio.h> #define SIZE 21 int te
#include <stdio.h>
#define SIZE 21
int temp_array[SIZE] = {0};
void sort(int array[], int start, int end);
void merge(int array[], int start_1, int end_1, int start_2, int end_2);
int main()
{
int array[SIZE] = {10, 1, 8, 3, 6, 5, 4, 7, 2, 9, 0, 100, 91, 98, 93, 96, 95, 94, 97, 92, 99};
sort(array, 0, SIZE-1);
for(int i = 0; i < SIZE; i++)
{
printf(" %i ", array[i]);
}
}
void sort(int array[], int start, int end)
{
if (end > start)
{
int middle = (start + end) / 2;
// sort left half
printf("sorting left half\n");
sort(array, start, middle);
// sort right half
printf("sorting right half\n");
sort(array, middle + 1, end);
// merge the two halves
printf("####MERGING#####\n");
merge(array, start, middle, middle + 1, end);
}
}
void merge(int array[], int start_1, int end_1, int start_2, int end_2)
{
int counter = 0;
int s1 = start_1;
while(start_1<=end_1 && start_2<=end_2)
{
printf(" %i %i and %i %i\n", start_1, end_1, start_2, end_2);
if(array[start_1] < array[start_2])
{
printf("selecting %i over %i\n", array[start_1], array[start_2]);
temp_array[counter++] = array[start_1++];
}
else
{
temp_array[counter++] = array[start_2++];
printf("selecting %i over %i\n", array[start_2], array[start_1]);
}
}
while (start_1 <= end_1)
{
temp_array[counter++] = array[start_1++];
printf("Dumping Left Half: placing %i in position %i\n", array[start_1], counter);
}
while (start_2 <= end_2)
{
temp_array[counter++] = array[start_2++];
printf(" Dumping Right Half: placing %i in position %i\n", array[start_2], counter);
}
for(int i = s1, j = 0; i <= end_2; j++, i++)
{
printf("Placing %i in position %i\n", temp_array[j], i);
array[i] = temp_array[j];
}
return;
}
#包括
#定义大小21
int temp_数组[SIZE]={0};
无效排序(int数组[],int开始,int结束);
无效合并(int数组[],int开始_1,int结束_1,int开始_2,int结束_2);
int main()
{
int数组[大小]={10,1,8,3,6,5,4,7,2,9,0,100,91,98,93,96,95,94,97,92,99};
排序(数组,0,大小为1);
对于(int i=0;i开始)
{
中间整数=(开始+结束)/2;
//排序左半
printf(“排序左半”);
排序(数组、开始、中间);
//将右半部分排序
printf(“排序右半”);
排序(数组,中间+1,结束);
//合并两半
printf(“合并”);
合并(数组、开始、中间、中间+1、结束);
}
}
无效合并(int数组[],int开始_1,int结束_1,int开始_2,int结束_2)
{
int计数器=0;
int s1=开始_1;
然而(开始)_1我觉得可疑的一件事是在合并代码中的else
:
temp_array[counter++] = array[start_2++];
printf("selecting %i over %i\n", array[start_2 /* HERE */], array[start_1]);
假设在执行上述操作之前,start_2==end_2
保持不变,则printf
将从索引end_2+1
中读取,这将超出sort
的最外层递归调用的范围,从而导致未定义的行为(这可能导致打印垃圾).稍微相关一点,如果你放弃所有的开始-结束配对,在递归调用中使用一个基址、一些指针算法和一个长度,那么这是一个多么容易的算法。在这方面,C是一个很好的东西。与你带来的算法一起跳舞吧。也就是说,调试器将是你的下一个turn.我没有否决这一点,只是因为内联消息调试显然已经尝试过了,这确实比大多数人来这里之前投入的精力要多。至少,这是一个道具。代码在我的机器上似乎运行得很好--你能给我们看一个你遇到的错误的例子吗?没有必要在标题中说源代码包括uded。我们有眼睛。注意:我在第一篇评论中提到的简单示例。如果有机会,我会看一看您的代码。感谢您的建议,我肯定可以看到您的示例是如何运行的,并且更简单。您打败了我,算法工作正常,调试消息正在生成越界访问。谢谢您,我认为代码是正确的,并且printf放在执行之后。开始使用调试器的动机更多。