快速排序的原理是找出一个基准值,然后定义两个索引,通过这两个索引,一个索引往后遍历,一个索引往前遍历.
1.后索引处理
先将后索引往前遍历,也就是下面代码定义的int end,我们为了不影响end的实际数值,将end赋给j,后续用j来操作后索引(目的最后面会讲),现在的目的是找到比基准值小的数(本该呆在基准值左边,却呆在右边的数),当找到时,j会停下
2.前索引处理
先将前索引往前遍历,也就是下面代码定义的int start,我们为了不影响end的实际数值,将end赋给j,后续用i来操作前索引(目的最后面会讲),现在的目的是找到比基准值大的数(本该呆在基准值右边,却呆在左边的数),当找到时,j会停下
3.索引错误输入处理
这里的if语句是判断前索引小于后索引,则判断输入索引有误,函数直接返回
void quickSort(int *arr, int start, int end) { int i = start; // i存储最最前 int j = end; // j存储最后 if (i >= j) { return ; }
4.索引开始遍历
我们交换两索引对应的值,(索引本身没有变),这里定义的pivot是基准值,可以是数列的任意一个值,一般我们定义第一个值为基准值,也就是我们传入的索引为start的位置,所以定义为
int pivot = arr[start]; ,此pivot值会后续用来交换.当i和j索引停下,我们需要交换i和j所对应的数值,此操作就是第一次将比基准值大的数排在了右边,将比基准值小的数排在了左边.最外层的while(i!=j)会使得这个操作执行到i==j为止.也就是这个最外层循环结束时,我们已经将比基准值小的值放在了基准值左边(但无序),将比基准值大的值或相等的放在了基准值右边(同样无序).
int pivot = arr[start]; while (i != j) { while (j > i && arr[j] > pivot) { j--; } // end找到位置 while (j > i && arr[i] < pivot) { i++; } // start找到位置 // 如果end>start交换 if (i < j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } }
5.索引相遇
while循环结束,说明此时i已经和j索引相遇,这是j与i指向的位置就是基准值要呆的位置,我们将基准值与arr[i]或arr[j]交换,此时我们才真正实现了基准值的左侧全是比其小的数,右侧全是比其大或相等的数.基准值将这个数列一分为二,左侧和右侧产生了两个新的无序数列,我们即可用递归重新将两个数列加入我们写的函数
// 跳出循环说明end == start ,交换基准值 int temp = pivot; pivot = arr[i]; arr[i] = temp; // 交换之后,数列被一分为二,end与start仍在刚开始的位置,而i和j到了基准值的位置 quickSort(arr,start,i-1); quickSort(arr,i+1,end);6.注意事项
这里不可以直接用start和end来操作while循环,我们用i和j来操作循环的目的就是为了保留start和end的原始值,方便在递归时使用.并且这里的代码是从上到下按顺序无缝拼接的一个函数,为了方便讲解,我才单独把每个模块贴出来
7342

被折叠的 条评论
为什么被折叠?



