package com.nspace.offer.algs.order;
import java.util.Arrays;
/**
* 抄写自算4 课本184页
*/
public class QuickOrder extends BaseOrder {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = {2, 5, 87, 1, 9, 14, 21, 56};
System.out.println(Arrays.toString(arr));
sort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
/*System.out.println("==========================");
int[] arr2 = {2, 5, 87, 1, 9, 14, 21, 56};
System.out.println(Arrays.toString(arr2));
sort2(arr2, 0, arr2.length - 1);
System.out.print(Arrays.toString(arr2));*/
}
public static void sort(int[] arr, int lo, int hi) {
if (hi <= lo) return;
int j = partition(arr, lo, hi);
sort(arr, lo, j - 1);
sort(arr, j + 1, hi);
}
public static void sort2(int[] arr, int lo, int hi) {
if (hi <= lo) return;
int j = partition2(arr, lo, hi);
sort2(arr, lo, j - 1);
sort2(arr, j + 1, hi);
}
/**
* 分区 将数据组切分为a[lo..i-1], a[i], a[i+1..hi]
* 使用头部基准值
* @param a
* @param lo
* @param hi
* @return 返回分区的位置
*/
public static int partition(int[] a, int lo, int hi) {
System.out.println("partition:[" + lo + "--" + hi + "]");
//将数据组切分为a[lo..i-1], a[i], a[i+1..hi]
int i = lo, j = hi + 1;//左右扫描指针
int pivot = a[lo];
while (true) {
//扫描左右,检查扫描左右是否结束并交换元素
while (a[++i] < pivot) {
if (i == hi) break;
}
while (a[--j] > pivot) {
if (j == lo) break;
}
if (i >= j) break;
swap(a, i, j);
}
System.out.println("swap-->lo[" + lo + "],j[" + j+"]");
swap(a, lo, j);
System.out.print("pivot:" + pivot+" ");
System.out.println(Arrays.toString(a));
return j;
}
/**
* 分区 将数据组切分为a[lo..i-1], a[i], a[i+1..hi]
* 使用尾部基准值来分区
* @param a
* @param lo
* @param hi
* @return 返回分区的位置
*/
public static int partition2(int[] a, int lo, int hi) {
//将数据组切分为a[lo..i-1], a[i], a[i+1..hi]
int i = lo-1, j = hi;//左右扫描指针
int pivot = a[hi];
while (true) {
//扫描左右,检查扫描左右是否结束并交换元素
while (a[++i] < pivot) {
if (i == hi) break;
}
while (a[--j] > pivot) {
if (j == lo) break;
}
if (i >= j) break;
swap(a, i, j);
}
swap(a, hi, i);
System.out.println("swap-->lo[" + lo + "],j[" + j+"]");
System.out.print("pivot:" + pivot);
System.out.println(Arrays.toString(a));
return i;
}
}
快速排序的基本思想
是基于冒泡排序改 进而来
第一步:
在数据集之中,选择一个元素作为"基准"(pivot)
第二步:
分区,于数组中选出一个基准值,把小于基准值的交换至左分区,大于基准值的交换至右分区,等于基准值的位于中间分区
第三步
对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止