在尝试用C语言编写一个mergesort作为练习时,我遇到了一个奇怪的问题,即算法的输出随着printf的存在而改变。让我进一步阐述。我有一个“MergeSort.h”文件,其中我的mergesort算法如下:
#ifndef _MSORT_H_
#define _MSORT_H_
void merge(int a[],int lo,int mi,int hi){
int n1 = (mi - lo) +1;
int n2 = hi - mi;
int left[n1];
int right[n2];
int i;
int j;
int k;
for(i = 0;i < n1;i++){
left[i] = a[lo+i];
}
for(j = 0;j < n2;j++){
right[j] = a[mi+j+1];
}
i = 0;
j = 0;
for(k = lo;k <= hi;k++){
if(left[i] < right[j]){
a[k] = left[i];
i = i + 1;
}else{
a[k] = right[j];
j = j+1;
}
}
}
void msorthelper(int a[],int p,int r){
if(p < r){
int mid = (p + r)/2;
msorthelper(a,0,mid);
msorthelper(a,mid+1,r);
merge(a,p,mid,r);
}
}
void msortex(int a[],int size){
msorthelper(a,0,size-1);
int counter;
for(counter = 0;counter < size;counter++){
printf(" %d ",a[counter]);
}
}
#endif
我在sorttester.c中有相应的排序测试器:
#include <stdio.h>
#include "mergesort.h"
int main(){
int out[] = {8,1,6};
msortex(out,3);
}
运行sorttester的输出如下:
1 0 0
现在这是有趣的部分,当我将任何printf语句放到合并的开头时,会生成正确的输出。这是一个例子:
#ifndef _MSORT_H_
#define _MSORT_H_
void merge(int a[],int lo,int mi,int hi){
printf("Hello\n");
int n1 = (mi - lo) +1;
int n2 = hi - mi;
int left[n1];
int right[n2];
.................Rest of the code.....
现在的输出是:
HelloHello 1 6 8
这是数组8 6 1的正确排序顺序。
有人可以告诉我这里我可能做错了什么导致输出因printf的存在而大幅增加?
由于
答案 0 :(得分:2)
查看代码的合并部分:
for(k = lo;k <= hi;k++){
if(left[i] < right[j]){
a[k] = left[i];
i = i + 1;
}else{
a[k] = right[j];
j = j+1;
}
}
让我们假设
left[] = {1, 2}
right[] = {3, 4, 5}
在合并循环(k)的2次迭代之后,“i”的值将为2.从现在开始,您将尝试比较
left[2] < right[j]
哪个是无效的,因为左[2]会引用一些随机存储器(左数组大小只有2,因此索引2的元素不存在,只有0和1)
因此,如果您为i和j值添加保护,例如首先将条件更改为:
if(i != n1 && (j == n2 || left[i] < right[j])){
你应该没事。
无论如何,我还应该告诉你,你不应该用不是const的值来声明数组大小,例如:
int left[n1];
int right[n2];
它实际上是被标准禁止的。您应该动态分配它,使用向量(如果是c ++)或jus声明它们是全局的,具有足够大的大小(最大n值)