排序算法(六):快速排序
一、排序原理
快速排序是对冒泡排序的一种改进。基本的思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的数据要小,然后按照此方法对这两部分的数据分别进行快速排序,排序过程递归进行,以此达到整个数据都变成有序序列。
具体的排序步骤如下:
- 首先设定一个分界值,通过该分界值将数组分成左右两部分。
- 将大于或等于分界值的数据放到数组右边,小于分界值的数据放到左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中的各元素都大于或等于分界值。
- 然后,分界值左侧和右侧的数据又可以独立进行排序,排序方式同步骤2.
- 重复上述过程,即进行递归操作,当左侧和右侧的数据都排序好后,整个数组的排序也就完成了。
二、排序实现
import java.util.Arrays; /** * 快速排序 */ public class QuickSort { public static void main(String[] args) { Integer[] arr = {4, 5, 3, 9, 2, 1}; sort(arr); System.out.println(Arrays.asList(arr).toString()); } public static void sort(Comparable[] a) { int lo = 0; int hi = a.length - 1; sort(a, lo, hi); } public static void sort(Comparable[] a, int lo, int hi) { // 安全校验 if (hi <= lo) { return; } // 需要对数组中lo索引到hi索引处的元素进行分组(分为:左子组和右子组) int partition = partition(a, lo, hi); // 返回的是分组的分界值所在的索引,即分界值变换后的索引 // 让左子组有序 sort(a, lo, partition - 1); // 让右子组有序 sort(a, partition + 1, hi); } // 对数组a中,从索引lo到hi之间的元素进行分组,并返回分组界限所对应的索引 private static int partition(Comparable[] a, int lo, int hi) { // 确定分界值 Comparable key = a[lo]; // 定义两个指针,分别指向待切分元素的最小索引处+1和最大索引处 int left = lo; int right = hi + 1; while (true) { while (less(key, a[--right])) { if (right == lo) { break; } } while (less(a[++left], key)) { if (left == hi) { break; } } if (left >= right) { break; } else { exch(a, left, right); } } int cutoffIndex = right; // 也可以等于left(因为此时left和right是相等的) exch(a, lo, cutoffIndex); return cutoffIndex; } private static boolean less(Comparable i, Comparable j) { return i.compareTo(j) < 0; } public static void exch(Comparable[] a, int i, int j) { Comparable temp = a[i]; a[i] = a[j]; a[j] = temp; } }
三、快速排序的时间复杂度
最优和平均情况:O(nlogn)
最坏情况:O(n^2)

浙公网安备 33010602011771号