一、快速排序介绍
1.快速排序是对冒泡排序的改进。冒泡排序每次交换只能使原序列的逆序数减一(相邻元素的交换),而快速排序可以进行不相邻元素的交换,逆序数至少减少1。(当排序序列逆序数为0时,排序就完成了)
- 百度百科的逆序数解释:
2.基本思想(以升序排序为例):
- 选定数组中的一个数作为参照数,将比其小的数放在其左边,大的放在其右边。
- 将其左边和右边的数看成新的数组,分别进行第一步的过程,之后循环进行,直到新的数组中只剩一个元素为止。
二、图解
下图中只用看思想,排序过程中实际数的顺序不一定是这样的。这里选每个数组中第一个数当参照数,实际参照数可以有多种选择方案。
三、代码分析
3.1交换函数
快排中最重要就是将比参照数小的放在其左边,大的放在其右边的方法。这里我看了一些文章,结合自己的思考,总结了三个方法。
(1)一直交换
这里定义两个指针分别指向数组的头与尾。
a. 判断尾指针所在元素是否小于参照数(即头指针指向的数),不小于,尾指针就一直向左移,直到找到小于参照数的数或到达头指针(两指针相遇,循环就结束),将头尾指针元素交换。
b.接着判断头指针所在元素是否大于参照数(即尾指针指向的数),不大于,头指针就一直向右移,直到找到大于参照数的数或到达尾指针(两指针相遇,循环就结束),将头尾指针元素交换。
c.反复进行步骤ab,直到头尾指针相遇。
**思考:**这样可以保证头指针前的都是小于参照数的,尾指针后的都是大于参照数的。
图解:
这里以arr={5, 4, 8, 2, 7, 1}为例
尾指针小于5,交换。(一定要尾指针先判断,因为头指针记录着参照数。)
头指针开始判断:
找到,交换。
尾指针开始判断。
找到,交换。
头指针开始判断。
两指针相遇,结束。
代码:
public static int change(int[] arr, int left, int right) {
int l = left;//头指针
int r = right;//尾指针
while(l < r){
while(arr[r] >= arr[l] && l < r){
r--;
}
int temp = arr[r];//交换
arr[r] = arr[l];
arr[l] = temp;
while(arr[l] <= arr[r] && l < r){
l++;
}
temp = arr[r