一.基本原理:
从待排数据序列中任取一个元素作为分界值(比如第一个),将所有比它大的放在右边,将所有比它小的放在左边,这样一次下来就得到了两个子序列,左边序列的数据元素的值都比临界值小,右边序列元素的值都比临界值大。将子序列也进行快速排序,如果排序还未完成,继续分成子序列进行快速排序,直到所有数据元素全部排序完成。
二、实例
这样一趟快速排序的算法如下:
1.设置两个值i=0,j=N(数组的最大索引)
2.第一个数组元素的值作为关键数据赋给key,key=a[0]
3.从j开始向前搜索,即从j开始通过j=j-1向前搜索,当遇到a[j]<key,交换两值。
4.从i开始向后搜索,即从i开始通过i=i+1向后搜索,当遇到a[i]>key,交换两值。
5.重复3.4步,直到i=j。
实例讲解:(升序)5.3,9,7,6,2,8,4,1将5赋给key
待排序的数组为
通过讲解的步骤开始运行
key=a[0]=5 j=8向前搜索,当搜索到j=8时a[j]<key,交换两值
a[ ] | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1 | 3 | 9 | 7 | 6 | 2 | 8 | 4 | 5 |
i=0向前搜索,当搜索到i=2时a[i]>key,交换两值
a[ ] | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1 | 3 | 5 | 7 | 6 | 2 | 8 | 4 | 9 |
然后重复3、4步
1 | 3 | 4 | 7 | 6 | 2 | 8 | 5 | 9 |
1 | 3 | 4 | 5 | 6 | 2 | 8 | 7 | 9 |
1 | 3 | 4 | 2 | 6 | 5 | 8 | 7 | 9 |
1 | 3 | 4 | 2 | 5 | 6 | 8 | 7 | 9 |
现在完成第一次排序后,i=j=4;
这样我们就完成了一趟快速排序,接下来只要对临界值前后两个子序列,将(i=0,j=i-1)和(i=j+1,j=N)作为两个新的序列进行快速排序
也就是子序列
1 | 3 | 4 | 2 |
和子序列
6 | 8 | 7 | 9 |
如果还未排序完毕,可再次将子序列分成新排序进行再次排序,直到排序完毕
第二次排序后:
1 | 3 | 4 | 2 | 5 | 6 | 8 | 7 | 9 |
第三排序后:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
排序完成
三、代码实现
我们发现,在实现排序的过程中我们用到了分而治之的思想,就是把大的转化成小的,把小的转化成更小的进行处理排序,所有我们在代码实现的过程中用到了递归进行分化,具体快速排序的java实现如下:
public class C {
public static void main(String[] args) {
int[] a = {5, 3, 9, 7, 6, 2, 8, 4, 1};
quickSort(a, 0, a.length - 1);
for (int i : a) {
System.out.print(i + " ");
}
}
public static void quickSort(int[] a, int start, int end) {
int i = start;
int j = end;
if (i >= j) {//如果i>=j说明前后两端已经向中间交换完毕,已经完全排好了序
return;
}
boolean flag = true;//规定方向,从左往右为真,反则为假
while (i != j) {//当左右相等时,左右分为两堆,左堆为较小,右堆为较大的
if (a[i] > a[j]) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
flag = !flag;//交换时转换方向
}
if (flag) {//如果为真,则向前一位搜索(j--)
j--;
} else {//如果为真,则向后一位搜索(i++)
i++;
}
}
//进行子序列的快速排序
i--;
j++;
quickSort(a, start, i);
quickSort(a, j, end);
}
}