快速排序的溢出问题



今天自己写了个《算法导论》上的快速排序,出现了stackover flow(栈溢出)的问题,经过排查,成功解决,特来分享,希望能帮到有类似问题的网友。

所谓的栈溢出就是数据越界

代码如下(错误版):

# include 
#define SIZE 10

void qsort(int *array, int min, int max);	//快速排序
int Partition(int array[], int min, int max);	//就地重排
void swap(int *p1, int *p2); //交换

int main(void)
{
	int array[SIZE] = { 43, 6, 76, 2, 9, 3, 88, 3, 6, 0 };
	qsort(array, 0, SIZE);
	for (int k = 0; k < SIZE; k++) //打印输出排序后的数组
		printf("%d,", array[k]);
	return 0;
}

void swap(int *p1, int *p2){	//交换函数
	int temp;
	temp = *p1;
	*p1 = *p2;
	*p2 = temp;


}
int Partition(int array[], int min, int max){	//就地重排
	int i, key;
	key = array[min];
	i = min - 1;

	for (int j = min; j < max; j++){	//判断并交换
		if (array[j]>key){
			i++;
			swap(&array[i], &array[j]);
		}
	}
	swap(&array[i++], &key);	//把主元放到中间
	return i++;
}

void qsort(int *array, int min, int max){	//递归
	if (min < max){
		int i = Partition( array,  min,  max);
		qsort(array, min, i--);
		qsort(array, i++, max);

	}
}
代码如下 (正确版):

# include 
# define TSIZE 45
#define SIZE 10

void swap(int *p1, int *p2);
int Partition(int array[], int min, int max);
void qsort(int *array, int min, int max);

int main(void)
{
	int array[SIZE] = { 43, 6, 76, 2, 9, 3, 88, 3, 6, 0 };
	qsort (array,0,SIZE);
	for (int k = 0; k < SIZE; k++)
		printf("%d,", array[k]);
	return 0;
}

void swap(int *p1, int *p2){	//交换
	int temp;
	temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

int Partition(int array[], int min, int max){	//重排交换,从大到小
	int i, key;
	key = array[min]; //指定第一个值为分界线
	i = min - 1;

	for (int j = min; j < max ; j++){
		if (array[j]>key){
			i++;
			swap(&array[i], &array[j]);
		}
	}
	swap(&array[++i], &key);//修正1
	return ++i ;//修正2
}
void qsort(int *array, int min, int max){ //递归调用快排
	if (min < max){
		int i = Partition( array,  min,  max);
		qsort(array, min, --i);	//修正3
		qsort(array, ++i, max);		//修正4

	}
}

在正确版代码中请注意看到我标注的“修正”,那几行就是要改的地方。把i++改成++i,为什么改成这样就可以避免溢出呢?因为

这两者是不一样的,虽然两者都是给i增加1,当写成i++时,程序是先用i的值之后再改变i,而++i则是先改变再用,很多情况下两者是可

以互换(你也可以使用 i = i+1的形式,但是没有人会相信你是一个真正的C程序员--《C primer plus》)。

但是在这里,如果你写成i++,那么到了递归阶段,第一次调用 qsort (array,min,i++)就会导致i为-1,有兴趣可以自己在大脑里推演推演(嗯,这是个快速杀死脑细胞的好方法),但是我们都知道,数组都是从0开始的。所以stackover flow就变得理所当然了。这也是为什么改成++i 就可以运行的原因。

最后,热烈欢迎大家的指正和批评,热烈欢迎大家一起探讨。

参考:

http://v.163.com/movie/2010/12/S/4/M6UTT5U0I_M6V2T7IS4.html (MIT算法导论公开课)



你可能感兴趣的:(算法,c,算法导论,递归,快速排序)