快排
从头开始学习算法,从最简单的排序算法开始,第一个接触的就是快排,学习的平台是 AcWing,希望现在学习还不晚,对以后能有帮助
快排的原理
快排使用的是分治的思想,有三个关键点:确定分界点、调整区间、递归处理左右两段,这里的思想是使用两个指针,分别对应数组的左右边界,一下简称 l 和 r,通过循环来将两个指针向中间移动直到 l 和 r 相遇,在这期间,将数组调整为小于等于分界点的值和大于等于分界点的值两部分,再使用递归的思想处理
首先要做的是确定一个分治的分界点,这个点可以是任意的一个数组元素,但不要给它设置成固定值,最好通过变量来对它进行定义,例如 array[l]、array[r]、array[(l + r) / 2] 这种都可以
然后通过分界点的值来调整数组空间,,这里需要用到刚才提到的 l 和 r 两个指针,过程是:先将 l 向后移动,检验 l 对应的值是否小于分界点,如果小于则继续后移 l,否则 l 就会停下,这是 r 开始前移,检测移动后的 r 所对应的值是否大于分界点,如果大于则继续前移 r,否则 r 也会停下,这个时候 l 和 r 都已经停下了,说明 l 和 r 都已经遇到了不属于自己对应空间的值,直接交换两个指针当前所对应的值,然后继续移动 l 和 r 指针,直到 l 和 r 相遇
最后便是使用递归的思想,对分界点左边(大小意义上的左,并非是排序上的左)和分界点右边的元素再进行第二步的过程,当最后一次递归结束后,数组便完成了排序
代码
void quick_sort (int[] arr, int l, int r) {
if (l == r)
return;
//x:分治变量 循环变量需在两侧边界外一个偏移量的位置,因为每次都是先让指针后/前移一格,所以循环变量需要在边界的前/后一个偏移量的位置
int x = arr[l], i = l - 1, j = r + 1;
while (i < j) {
do
i++;
while (arr[i] < x);
do
j++;
while (arr[j] > x);
if (i < j)
swap(arr[i], arr[j]);
}
quick_sort(arr, l, j);
quick_sort(arr, j + 1, r);
}