快速排序是什么
快排算法是基于分治策略的排序算法,具有高效特点。快速排序过程能通过递归进行,最后使得数组变成有序的序列,我分享的是从数组的两头开始的。废话不多说,直接预备备!(先奉上代码,后面有举例详解步骤。详细步骤配合注释如果看不懂,请来砍我!)
大致思路,一开始从双端向中间扫描,基准值作为轴,把数组分成两部分,左边的都小于基准值,右边的都大于基准值,递归
快排代码(java)
public void quicksort(int s[], int left, int right) {
if (left < right) {
int i = left, j = right, x = s[left];// 最左边下标记为i,最右边记为j,基准值设置为数组最左边的元素
while (i < j) // 当左边的下标i,仍然小于右边下标j
{
// 从j出发,从右向左找第一个,小于基准值的元素(当右边下标j的元素值大于x时,持续向左移动)
while (i < j && s[j] >= x) // 当左边的下标i,仍然小于右边下标j,并且右边下标j的元素值大于等于基准值
j--; // 右边向左移动一位
if (i < j) // 如果,右边下标j大于左边下标i
s[i++] = s[j]; // 那么,先把找到的下标j的元素值,赋值给 下标i元素值,然后i自增1
// 从i出发,从左向右找第一个,大于基准值的元素(当左边下标i的元素值小于x时,持续向右移动)
while (i < j && s[i] < x) // 当左边的下标i,仍然小于右边下标j,并且左边下标的元素值小于基准值
i++; // 左边向右移动一位
if (i < j) // 如果,右边下标j大于左边下标i
s[j--] = s[i]; // 那么,就把找到的下标i的元素值,赋值给 下标j元素值,然后j自减1
}
//如果i,j碰面
s[i] = x; // 把基准值赋值给左边下标停止位置i
quicksort(s, left, i - 1); // 递归调用 (给左边部分快排)
quicksort(s, i + 1, right); // 递归调用 ( 给右边部分快排)
}
}
举?图解
假设有一个数组,int b[] = { 8, 1, 9, 7, 3, 4, 2, 5, 10, 6 },首先,把用 i 保存最左边的下标,用 j 保存最右边的下标,并且把最左边的元素设置为x,作为基准值。(选择基准值有其他方式,会有使得排序达到更高的效率,这里不延伸)
下标 | 0 (i) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 (j) |
元素值 | 8 (x) | 1 | 9 | 7 | 3 | 4 | 2 | 5 | 10 | 6 |
注意:当i<j仍然成立,那么本次循环也依旧继续
第一趟循坏:
①步骤
首先从下标 j 出发,寻找小于基准值 x (x=8)的元素,找到以后我们暂停下来观察一下。容易发现,找到的元素值是 6,此时 b[j] = b[9] = 6
下标
0 (i)
1
2
3
4
5
6
7
8
9 (j)
元素值
8 (x)
1
9
7
3
4
2
5
10
6
停下来以后,再将与b[j]赋值给b[i],然后i自增1。看到这里,有些小伙伴这里可能会疑惑,b[i]被覆盖了,那岂不是出乱子了,莫得了一个元素ヾ(≧O≦)〃嗷~。不过不要慌,我们一开始,是把b[i]作为基准值保存在了x中。这样一顿操作下来,现在的战况是:
b[] = { 6, 1, 9, 7, 3, 4, 2, 5, 10, 6 }.如图:
下标
0
1(i)
2
3
4
5
6
7
8
9(j)
元素值
6
1
9
7
3
4
2
5
10
6
②步骤
现在右边开始的操作完了,开始左边的,从下标 i 出发,此时的下标i=1,寻找大于基准值 x (x=8)的元素,(逐个对比,一直i++,看找不找得到,一直到不满足i<j,找不到就去③),找到以后发现,找到的元素值是 9,然后找到的的元素值,赋值给 下标j元素值,然后j自减1,
,这样一顿操作下来,
现在的战况是:b[] = { 6, 1, 9, 7, 3, 4, 2, 5, 10, 9 }.如图:
下标
0
1
2(i)
3
4
5
6
7
8(j)
9
元素值
6
1
9
7
3
4
2
5
10
9
x=8
这两顿操作完,发现i<j依旧成立,所以得继续做①+②这两个步骤,再做一次①,
从下标 j 出发,寻找小于基准值 x (x=8)的元素,找到以后停下来。容易发现,找到的元素值是 5,此时 b[j] = b[7] = 5,停下来以后,再将与b[j]赋值给b[i],然后i自增1。得到:
下标
0
1
2
3(i)
4
5
6
7(j)
8
9
元素值
6
1
5
7
3
4
2
5
10
9
x=8
再做一次②,一直i++,逐个对比,发现i已经不满足i<j了,还是找不到,所以步骤③
③步骤
把基准值赋值给b[i](这很关键) 得到:
下标
0
1
2
3
4
5
6
7(j)(i)
8
9
元素值
6
1
5
7
3
4
2
8
10
9
x=8
那么本次循环结束,开始递归。希望可以帮到大家