public class QuickSort {
public static void main(String[] args) {
QuickSort sorter = new QuickSort();
int src[] = { 10, 9,8,7,6,5,4,3};
sorter.quickSort(src, 0, src.length-1, 3);
for (int i : src) {
System.out.print(i + " ");
}
}
/**
*
* @param src
* @param first
* @param last
* @param minSortNum
* 当最小值为多少的时候不再进行快速排序,而是直接用插入排序来解决
*/
private void quickSort(int[] src, int first, int last, int minSortNum) {
if (last - first + 1 <= minSortNum) {
insertSort(src, first, last);
return;
}
int pivotIndex = partition(src, first, last);//对数组实现划分
quickSort(src, first, pivotIndex, minSortNum);
quickSort(src, pivotIndex + 1, last, minSortNum);
}
/**
* 插入排序的代码
*
* @param src
* @param first
* @param last
*/
private void insertSort(int[] src, int first, int last) {
for (int i = first + 1; i <= last - first; ++i) {
int temp = src[i];
int j = i;
while (j > 0 && src[j - 1] > temp) {
src[j] = src[j - 1];
j--;
}
src[j] = temp;
}
}
/**
* Task:让支点前所有的元素都比支点小,支点后所有的元素都比支点大
* 从第二个元素向右寻找,从倒数第三个元素开始向前寻找(因为支点在之前已经被交换到倒数第二个元素,所以倒数第二个元素无需比较)
*
* 如果下标为IndexFromLeft的元素小于下标为IndexFromRight的元素,并且IndexFromLeft<IndexFromRight,那么将其交换位置
* 因为向右最终将到达支点处,所以不用考虑出界的问题
* @param src
* @param first
* @param last
* @return支点的下标
*/
private int partition(int[] src, int first, int last) {
int mid = findPivot(src, first, last);
int pivotNum = src[mid];//得到支点的数值
swap(src, mid, last - 1);//将支点与倒数第二个元素进行交换
int indexFromLeft = first + 1;//设置最开始查找的元素为第一个,因为第0个元素一定比支点小
int indexFromRight = last - 2;
boolean done = false;
while (!done) {
while (src[indexFromLeft] < pivotNum) {
indexFromLeft++;
}
while (src[indexFromRight] > pivotNum) {
indexFromRight--;
}
if (indexFromLeft < indexFromRight) {
swap(src, indexFromLeft, indexFromRight);
indexFromLeft++;
indexFromRight--;
} else {
done = true;
}
}
swap(src, last - 1, indexFromLeft);
int pivotInex = indexFromLeft;
return pivotInex;
}
//排序两个元素
private void sort2Element(int[] src, int one, int two) {
if (src[one] > src[two]) {
swap(src, one, two);
}
}
/**
* 支点为前中后三个元素的排序,将其排序后在中间的元素即为支点,将这三个元素按照大小顺序排序好(进行交换)
*/
private int findPivot(int[] src, int first, int last) {
int mid = (first + last) / 2;
sort2Element(src, first, mid);
sort2Element(src, mid, last);
sort2Element(src, first, mid);
return mid;
}
private void swap(int[] src, int one, int two) {
int temp = 0;
temp = src[one];
src[one] = src[two];
src[two] = temp;
}
}