快速排序:快排是一种不稳定的算法,其平均时间复杂度为O(nlgn),最坏为O(n^2)。
设当前待排序的无序区为R[low..high],那么在R[low..high]中任选一个记录作为基准(Pivot),以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1]和R[pivotpos+1..high],并使左边子区间所有记录的值小于等于基准值,右边子区间所有记录的值大于等于基准值,这时基准值就会处于正确的位置上。
/** * 快速排序(不稳定) * * @author alchimie */ public class QuickSort { public void sort(int[] arrs) { sort(arrs, 0, arrs.length - 1); } private void sort(int[] arrs, int low, int high) { int p; if (low < high) { p = partition(arrs, low, high); sort(arrs, low, p - 1); sort(arrs, p + 1, high); } } private int partition(int[] arrs, int left, int right) { int i, j, c, p; p = arrs[left]; // p中存的就是基准数 i = left; j = right; while (i != j) { // 顺序很重要,要先从右边开始找,否则i指针有可能停留在比p大的数上,导致归位交换出错 while (arrs[j] >= p && i < j) j--; // 再找右边的 while (arrs[i] <= p && i < j) i++; // 交换两个数在数组中的位置 if (i < j) { c = arrs[i]; arrs[i] = arrs[j]; arrs[j] = c; } } // 最终将基准数归位 // System.out.println("===" + "arrs[left]="+ arrs[left] + ", arrs[i]="+ // arrs[i]+"==="); arrs[left] = arrs[i]; arrs[i] = p; System.out.println("基准数: " + p + " " + Arrays.toString(arrs)); return i; } public static void main(String args[]) { QuickSort qs = new QuickSort(); int arrs[] = { 49, 38, 65, 97, 76, 13, 27, 49 }; qs.sort(arrs); for (int i = 0; i < arrs.length; i++) { System.out.println(arrs[i]); } } }
执行结果:
基准数: 49 [13, 38, 27, 49, 76, 97, 65, 49]
基准数: 13 [13, 38, 27, 49, 76, 97, 65, 49]
基准数: 38 [13, 27, 38, 49, 76, 97, 65, 49]
基准数: 76 [13, 27, 38, 49, 65, 49, 76, 97]
基准数: 65 [13, 27, 38, 49, 49, 65, 76, 97]
13
27
38
49
49
65
76
97