package com.hao.algorithms.sort;
/**
* 常见排序算法
* @Author hao.wang
* @Date 2019/12/10 9:44
*/
public class SortAlgo {
/**
*选择排序
* 时间复杂度:平均O(N^2),最好O(n^2), 最坏O(n^2)
* 空间复杂度:O(1)
* @param array
*/
public static void selectionSort(Comparable[] array){
int length = array.length;
for (int i = 0; i < length; i++) {
for (int j = i+1; j < length;j++) {
if(less(array[j],array[i])){
swap(array,i,j);
}
}
}
}
/**
* 插入排序
* 时间复杂度:平均O(N^2),最好O(n), 最坏O(n^2)
* 空间复杂度:O(1)
* @param array
*/
public static void insertionSort(Comparable[] array){
int length = array.length;
for (int i = 1; i < length; i++) {
for (int j = i; j >0 && less(array[j],array[j-1]); j--) {
swap(array,j, j - 1);
}
}
}
/**
* 希尔排序
* 时间复杂度:平均O(N^1.3),最好O(n), 最坏O(n^2)
* 空间复杂度:O(1)
* @param array
*/
public static void shellSort(Comparable[] array){
int length = array.length;
int h = 1;
while (h < length / 3) {
h = h * 3 + 1;
}
while (h >= 1) {
for (int i = h; i < length; i++) {
for (int j = i; j >= h && less(array[j],array[j-h]) ; j-=h) {
swap(array,j,j-1);
}
}
h = h/3;
}
}
/**
* 自顶向下的归并排序
* 时间复杂度:平均O(NlogN),最好O(NlogN), 最坏O(NlogN)
* 空间复杂度:O(N)
* @param array
*/
private static Comparable[] aux;//归并所需的辅助数组
public static void mergeSort(Comparable[] array){
aux = new Comparable[array.length];
mergeSort(array,0, array.length-1);
}
/**
* 递归归并
* @param array
* @param left
* @param right
*/
private static void mergeSort(Comparable[] array,int left,int right){
if (left >= right) {
return;
}
int mid = (left + right) / 2;
mergeSort(array,left,mid);
mergeSort(array,mid+1,right);
merge(array, left, mid, right);
}
/**
* 自底向上的归并排序
* 时间复杂度:平均O(NlogN),最好O(NlogN), 最坏O(NlogN)
* 空间复杂度:O(N)
* @param array
*/
public static void mergeBUSort(Comparable[] array){
aux = new Comparable[array.length];
int length = array.length;
for (int sz = 1; sz < length; sz *= 2) {
for (int left = 0; left < length - sz; left += sz * 2) {
merge(array, left, left + sz -1, Math.min(left + sz * 2 - 1,length-1));
}
}
}
/**
* 快速排序
* 时间复杂度:平均O(NlogN),最好O(NlogN), 最坏O( n^2 )
* 空间复杂度:最差O(N),最优O(logn)
* @param array
*/
public static void quickSort(Comparable[] array){
quickSort(array,0,array.length-1);
}
private static void quickSort(Comparable[] array, int left, int right) {
if (right <= left) {
return;
}
int j = partition(array, left, right);
quickSort(array,left,j-1);
quickSort(array,j+1,right);
}
private static int partition(Comparable[] array, int left, int right) {
int i = left, j = right + 1;
Comparable temp = array[left];
while (true) {
while (less(array[++i], temp)) {
if (i == right) {
break;
}
}
while (less(temp,array[--j])) {
if (j == left) {
break;
}
}
if (i >= j) {
break;
}
swap(array,i,j);
}
swap(array,left,j);
return j;
}
/**
* 原地归并
* @param array
* @param left
* @param mid
* @param right
*/
private static void merge(Comparable[] array,int left,int mid,int right){
int i = left, j = mid + 1;
for (int k = left; k <= right; k++) {
aux[k] = array[k];
}
for (int k = left; k <= right ; k++) {
if (i > mid) {
array[k] = aux[j];
}else if(j > right){
array[k] = aux[i];
}else if(less(aux[i], aux[j])){
array[k] = aux[i++];
}else{
array[k] = aux[j++];
}
}
}
/**
* 比较元素
* @param v
* @param w
* @return
*/
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
/**
* 交换元素
* @param array
* @param i
* @param j
*/
private static void swap(Comparable[] array,int i, int j) {
Comparable temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static void main(String[] args) {
Integer[] array = {10, 3, 5, 6, 1, 4, 8};
// insertionSort(array);
// selectionSort(array);
// shellSort(array);
// mergeSort(array);
// mergeBUSort(array);
quickSort(array);
printArray(array);
}
private static void printArray(Comparable[] array) {
for (Comparable comparable : array) {
System.out.print(comparable.toString()+",");
}
}
}