快速排序
1. 算法思想
快速排序的核心算法思想是二分法(递归算法的经典实现),例如:数组arr{ 5,7,1,4,3,6,2 }
以5为基准,比5小的数构成一个左数组{ 4,2 },比5大的数构成一个右数组{ 6,7,8 }
然后左数组以4为基准进行排序,右数组以6为基准进行排序……
具体排序规则如下:
声明两个指针i,j分别指向数组最左端和最右端
声明临时变量temp记录数组最左端的值
5 | 7 | 1 | 4 | 3 | 6 | 2 |
---|---|---|---|---|---|---|
i | j | |||||
temp=5 |
①先看右端的 j,如果arr[ j ] >= 5则指针 j 左移一位;若arr[ j ] < 5,这时说明arr[ j ]也就是2出现在了不该出现的位置(因为我们希望比5小的数出现在左边),把 j 放在这里不动,去看左边的指针 i。
②若arr[ i ] < 5 ,则指针 i 向右移;直到发现arr[ i ] >= 5 的情况:
5 | 7 | 1 | 4 | 3 | 6 | 2 |
---|---|---|---|---|---|---|
i | j | |||||
temp=5 |
也是确定下 i 的位置。
③比较 i 和 j 的大小,确定i < j(确定 i 在 j 的左侧,且不包括重合的情况),则执行交换:
5 | 2 | 1 | 4 | 3 | 6 | 7 |
---|---|---|---|---|---|---|
i | j | |||||
temp=5 |
④重复①②③……的步骤,直至 i = j 的情况出现
5 | 2 | 1 | 4 | 3 | 6 | 7 |
---|---|---|---|---|---|---|
i,j | ||||||
temp=5 |
这时交换temp(之前记录了数组最左端arr[0]的值)与arr[ i ](或arr[ j ])的值(因为指向同一个位置),得:
3 | 2 | 1 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|
i,j | ||||||
temp=5 |
这时,数值5已经确定了有序数组中的位置(左边有4个比5小的数,右边有2个比5大的数,数值5的位置不再随着接下来的排序发生改变)
⑤以最左端的3为基准,重复①②③④,直至各数都确认了自己的位置,或某个子数组只有一个元素时,排序结束。
2. 代码实现
public class QuickSort {
// 快速排序
public void quickSort(int[] arr, int left, int right) {
if (left > right) {
return;
}
int temp = arr[left];
int i = left;
int j = right;
while (i != j) {
while (arr[j] >= temp && j > i) {
j--;
}
while (arr[i] <= temp && j > i) {
i++;
}
if (j > i) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
arr[left] = arr[j];
arr[j] = temp;
quickSort(arr, left, i - 1);
quickSort(arr, i + 1, right);
}
public void show(int[] arr) {
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
QuickSort qs = new QuickSort();
int[] arr = {
16, 54, 25, 3, 99, 0, 6, 3 };
qs.show(arr);
qs.quickSort(arr, 0, arr.length - 1);
qs.show(arr);
}
}
3. 运行结果
4. 过程分析
例:{ 5 , 7 , 4 , 6 , 2 , 8 }
{ 5,7 , 4,6,2,8 }{ 5,2,4,6,7,8 }{ 4,2,5,6,7,8 }
{ 4,2 } { 5 } { 6,7,8 }
{ 4,2 }{ 2,4 } | { 6,7,8 }{ 6,7,8 }
{ 2 }{ 2 } | | | { 7,8 }{ 7,8 }
| | | | | { 8 }{ 8 }
| | | | | |
最终结果为:{ 2,4,5 , 6 , 7 , 8 }