今天在学习用C语言写快排序的时候,遇到了一个问题,先直接看之前错误的代码:
//交换排序
//1,冒泡排序
//2.快速排序
static int iPartSort(int* a, int left, int right)
{
int key = left;
while(left < right)
{
//左边找大
while(left < right && a[left] <= a[key])
{
left++;
}
//右边找小
while(left < right && a[right] >= a[key])
{
right--;
}
Swap(&a[left], &a[right]);
}
Swap(&a[left], &a[key]);
return left;
}
void vQuickSort(int* a, int begin, int end)
{
int key;
//区间没有值或区间不存在
if(begin >= end)
{
return;
}
key = iPartSort(a, begin, end);
//此时区间被分为3份:[begin,key-1],key,[key+1,end]
//继续递归
vQuickSort(a, begin, key-1);
vQuickSort(a, key+1, end);
}
写完代码进行测试时没有成功,就进行了调试,反复观察调试运行过程后,终于发现了问题所在
我们看红色框住的地方,我是将比较值的下标设为一个数组起始地址的,然后进行蓝色框住的代码,这里,就是出错的原因,下面,我们拿我这个错误代码的逻辑做个实例:
(升序)假设我给的一个需要排序的数组值为:
此时第一次进入快排时:
那么通过我的这个错误代码逻辑,经过第一次排序后,先进入蓝框中代码的“左边找大”,出循环后left为1,再进入“右边找小”,出循环后right为1,再交换两下标所对应的值.此时,出while(left>right)循环,再进行left下标与key下标对应值的交换。第一次排序后数组值变化为:
仔细看红框里的值,我找出了第一个key下标值后,按理说a[1]这里的值就是最后排序的最终值,是不会改变的,但很明显出了问题,我是升序,为什么a[1]的值会比a[0]的值小,第一次排序后a[key]的值就是最终排序的值,这里明显出了问题。那么,为什么呢?
我调试后发现,我排序时a[left]的值在与a[key]交换时,a[left]是不能比a[key]的值大的,不然就会出现上述问题,经过思考和调试后,终于是找出了解决方法:
红框中为代码解释
其实问题很简单,但往往越是简单的问题我们越难以发现,越是致命。
此文章仅以自己在学习中所遇到的问题进行记录