赞
踩
普通快速排序(以升序为例):
实现方式
1. 单边循环快排
a. 选择最右元素作为基准点元素;
b. j指针负责找到比基准点小的元素,一旦找到则与i进行交换;
c. i指针维护小于基准点元素的边界,也是每次交换的目标索引;
d. 最后基准点与i交换,i即为分区位置。
import java.util.Arrays; /** * 单边循环快排 */ public class Task04_QuickSort1 { public static void main(String[] args) { int[] a = {5, 3, 7, 2, 9, 8, 1, 4}; quick(a, 0, a.length-1); } public static void quick(int[] a,int l,int h){ if (l >= h){ return ; } int p = partition(a, l, h); // p 索引值 quick(a, l,p - 1); // 左边分区的范围确定 quick(a,p + 1, h); // 右边分区的范围确定 } public static int partition(int[] a,int l, int h){ int pv = a[h]; // 基准点元素 int i = l; // 每次交换的目标索引 for (int j = l;j < h;j++){ if (a[j] < pv){ // 优化 if (i != j) { swap(a, i, j); } i++; } } // 优化 if (i != h){ swap(a, i, h); } System.out.println(Arrays.toString(a) + " i=" + i); // 返回值代表了基准点元素所在的正确索引,用它确定下一轮分区的边界 return i; } public static void swap(int[] a,int i,int j) { int t = a[i]; a[i] = a[j]; a[j] = t; } }
2. 双边循环快排
a. 选择最左元素作为基准点元素;
b. j指针负责从右往左找到比基准点小的元素,i指针负责从左往右找到比基准点大的元素,一旦找到二者交换,直至i,j相交;
c. 最后基准点与i(此时i与j相等)交换,i即为分区位置。
public static int partition(int[] a,int l, int h){ int pv = a[l]; int i = l; int j = h; while (i < j){ // j 从右往左找小的 while (i < j && a[j] > pv){ j--; } // i 从左往右找大的 // i < j:5 1 2 3 6 7 8 9,pv=5,j=3,i=5 // i一直到6,才找到比基准大的,如果没有i<j,基准点5要被6交换走了 // <= :防止一开始时,基准点元素被交换 while (i < j && a[i] <= pv){ i++; } swap(a, i, j); } // 基准点元素与i交换 swap(a, l, i); System.out.println(Arrays.toString(a)+" i="+i); return i; }
要点:
特点:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。