package com.wj;
import java.util.Arrays;
public class Sort {
public static void main(String[] args) {
// int[] a = {1,2,3,4,9,8,7,6,5,0,1,3,0};
int[] a = {1,2,3,4,9,8,7,6,5,0,8};
// int[] a = {4,5,6,3,2,1};
// test1(a);
// test2(a);
// test3(a);
// test4(a);
// test5(a);
test6(a);
// test7(a);
System.out.println(Arrays.toString(a));
}
/**
* 冒泡排序
* @param a
*/
private static void test1(int[] a){
int len = a.length;
for (int i = 0; i < len; ++i) {
for (int j = 0; j < len - i - 1; ++j) {
if (a[j] > a[j + 1]) {
swap(a, j, j + 1);
}
}
}
}
/**
* 插入排序
* @param a
*/
private static void test2(int[] a){
int len = a.length;
for (int i = 1; i < len; ++i) {
int tmp = a[i];
int j = i - 1;
for (; j >=0; --j) {
if (a[j] > tmp) {
a[j + 1] = a[j];
} else {
break;
}
}
a[j + 1] = tmp;
}
}
/**
* 选择排序
* @param a
*/
private static void test3(int[] a){
int len = a.length;
for (int i = 0; i < len - 1; i++) {
int min = i;
for (int j = i; j < len; j++) {
if (a[j] < a[min]) {
min = j;
}
}
if (min > i) {
swap(a, i, min);
}
}
}
/**
* 归并排序
* @param a
*/
private static void test4(int[] a){
int len = a.length;
// merge(a, 0, len - 1);
merge2(a, 0, len - 1);
}
/**
* 快速排序
* @param a
*/
private static void test5(int[] a){
int len = a.length;
quick(a, 0 , len - 1);
}
/**
* 双路快速排序
* @param a
*/
private static void test6(int[] a){
int len = a.length;
quick2(a, 0, len - 1);
}
/**
* 三路快速排序
* @param a
*/
private static void test7(int[] a){
int len = a.length;
quick3(a, 0, len - 1);
}
private static void quick3(int[] a, int l, int r) {
if (l >= r) return;
int[] p = getP3(a, l , r);
quick2(a, l, p[0]);
quick(a, p[1], r);
}
private static int[] getP3(int[] a, int l, int r) {
int v = a[l];
int i = l;
int j = r + 1;
int k = l + 1;
while (k < j) {
if (a[k] < v) {
swap(a, k++, ++i);
} else if (a[k] > v){
swap(a, k, --j);
} else {
++k;
}
}
swap(a, l, i--);
return new int[]{i, j};
}
private static void quick2(int[] a, int l, int r) {
if (l >= r) return;
int p = getP2(a, l , r);
quick2(a, l, p - 1);
quick(a, p - 1, r);
}
private static int getP2(int[] a, int l, int r) {
int v = a[l];
int i = l + 1;
int j = r;
while(true){
while (i < j && a[i] < v) {
++i;
}
while (j > i && a[j] > v) {
--j;
}
if (i == j) break;
swap(a, i++, j--);
}
swap(a, i, l);
return i;
}
private static void quick(int[] a, int l, int r) {
if (l >= r) return;
int p = getP(a, l, r);
quick(a, l, p - 1);
quick(a, p + 1, r);
}
private static int getP(int[] a, int l, int r) {
int v = a[l];
int i = l;
for (int j = l + 1; j <= r; ++j) {
if (a[j] < v) {
swap(a, i + 1, j);
++i;
}
}
swap(a, l, i);
return i;
}
/**
* 自底向上排序
* @param a
* @param left
* @param right
*/
private static void merge2(int[] a, int left, int right) {
for (int i = 1; i < right; i += i) {
for (int j = 0; j + i <= right; j += 2 * i) {
mergeSort(a, j, j + i - 1, (j + 2 * i - 1 > right ? right : j + 2 * i - 1));
}
}
}
/**
* 自顶向下排序
* @param a
* @param left
* @param right
*/
private static void merge(int[] a, int left, int right) {
if (left >= right) return;
int mid = left + (right - left ) / 2;
merge(a, left, mid);
merge(a, mid + 1, right);
mergeSort(a, left, mid, right);
}
private static void mergeSort(int[] a, int left, int mid, int right) {
int[] tmp = Arrays.copyOfRange(a, left, right + 1);
int i = left;
int j = mid + 1;
for (int k = left; k <= right; ++k ) {
if (i > mid) {
a[k] = tmp[j - left];
++j;
} else if (j > right) {
a[k] = tmp[i - left];
++i;
} else if (tmp[i - left] < tmp[j - left]) {
a[k] = tmp[i - left];
++i;
} else {
a[k] = tmp [j - left];
++j;
}
}
}
private static void swap(int[] a, int i, int j){
if (a[i] == a[j]) return;
a[i] = a[i] ^ a[j];
a[j] = a[i] ^ a[j];
a[i] = a[i] ^ a[j];
}
}