package cn.ourpass.sorts;
import cn.ourpass.util.SystemUtils;
/**
* 排序学习
* @author simple
*
*/
public class SortTest {
public static void main(String[] args) {
int[] arr = {6, 22, 4, 7, 36, 1, 15, 99, 12};
SystemUtils.printArray(arr);
// insertSort(arr);
// shellSort(arr);
// bubbleSort(arr);
quickSort(arr, 0, arr.length-1);
SystemUtils.printArray(arr);
// int index = binarySearch(arr, 5);
// System.out.println(index);
}
/**
* 快速排序
* 如书述,快速排序是从冒泡排序进化而来,来由和shell排序类型
* @param arr
* @param low
* @param high
* @desc from apei830 of csdn
*/
private static void quickSort(int[] arr, int start, int end) {
if(start >= end) {
return;
}
int pivot = arr[start];
int i = start + 1;
int j = end;
while(true) {
while(i <= end && arr[i] < pivot) {
i++;
}
while(j > start && arr[j] > pivot) {
j--;
}
if(i < j) {
swap(arr, i, j);
} else {
break;
}
}
swap(arr, start, j);
quickSort(arr, start, j-1);
quickSort(arr, j+1, end);
}
public static void swap(int[] arr, int i, int j) {
if(i == j) {
return;
}
arr[i] = arr[i] + arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j];
}
/**
* 冒泡排序
* @param arr
*/
public static void bubbleSort(int[] arr) {
for(int i=0; i<arr.length; i++) {
for(int j=i+1; j<arr.length; j++) {
if(arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
/**
* 希尔排序
* @desc 希尔排序基于插入排序的n值越小、正序时,效率越高的 特性优化的
* @think shell当时应该是看到插入排序之后,计算它的时间复杂度,然后根据关系,得出这样的排序的。
* 数学果然很神奇,直接通过证明,就可能得出新的理论。
* 难怪数学家都想证明1+1=2呢!!
* @param arr
*/
public static void shellSort(int[] arr) {
//计算出初始的间隔值
int h = 1;
while(h <= arr.length / 3) {
h = h * 3 + 1;
}
while(h > 0) {
//插入排序
for(int i=h; i<arr.length; i += h) {
int currentVal = arr[i];
int position = i;
for(int j=i-h; j>=0; j -= h) {
if(arr[j] > currentVal) {
arr[j+h] = arr[j];
position = j;
} else {
break;
}
}
arr[position] = currentVal;
}
//计算下一个间隔值
h = (h-1) / 3;
}
}
/**
* 插入排序
* @param arr
*/
public static void insertSort(int[] arr) {
if(arr == null || arr.length < 2) {
return;
}
//从1开始,默认0已经排好了
for(int i=1; i<arr.length; i++) {
int currentVal = arr[i];
int position = i;
//从当前的前1个开始,倒着向前比较
for(int j=i-1; j>=0; j--) {
//如果j值大于当前值,
//则将j值后移1位,并记录移动后当前值应该在的坐标
if(arr[j] > currentVal) {
arr[j+1] = arr[j];
position = j;
} else {//如果顺序刚好,就结束比较
break;
}
}
//将当前值赋值给已记录的应该在的坐标
arr[position] = currentVal;
}
}
/**
* 折半查找
* @param arr
* @param val
* @return
*/
public static int binarySearch(int[] arr, int val) {
int start = 0, end = arr.length-1;
int mid = 0;
int i=0;
while(end > start) {
mid = (start + end) / 2;
i++;
System.out.println("searchTime:" + i + ";start:" + start + ",mid:" + mid + ",end:" + end);
if(arr[mid] > val) {
end = mid-1;
System.out.println("start:" + start + ",mid:" + mid + ",end:" + end);
} else if(arr[mid] < val) {
start = mid+1;
System.out.println("start:" + start + ",mid:" + mid + ",end:" + end);
} else {
break;
}
}
return end == start ? start : mid;
}
}