/**
*
* @Description:快排算法
* 快排算法基于划分操作,所谓划分操作即把大于一个临界值的全部放在一边,把小于临界值的全部放在另一边,对于临界值的选择会影响快排的效率
* 为了方便,一般快排中会将需要排序的数组的最右端值作为临界值,在划分操作结束后,把最右端的这个值放到划分的临界点上,这样就形成了一个相对有序的序列
* 但是直接使用最右端的值作为临界值,在面对特殊情况,如逆序排列的数组时,会导致效率降低,因此使用改进的方法,即在需要排序的数组中间、最左端、最右端的三个数中进行选择,挑选三个数中中等大小的数值作为临界值
* 在实际实现中,把三个数中最小的数放在最左端,最大的数放在最右端,中等的数,也就是临界值,放在最右端的左边一位
* 在划分操作时,直接在最右端的右边一位到最左端的左边两位进行,如图:[最小值,…需要划分…,中间值(临界值),最大值]
* 这么做的目的是可以减少若干操作,临界值放在两类数的边界上,即意味着,临界值到达了他在最终排序序列中的位置,因为临界值的左边都小于他,右边都大于他,这样就可以在接下来的递归调用中不再考虑这个临界值
* 同时最大值,最小值放在以前以后,可以在划分操作的时候不用考虑这两个数,因为他们已经在应该在的那边了,但是在后续递归的快排中,这里的最大值和最小值还是要参与的
* 划分操作结束后,把中间值换到临界值的位置上,然后对两边分别进行快排操作,如图:[最小值,…需要快排…,中间值,…需要快排…,最大值]
* 因为使用了三选一选临界值的方法,所以当需要递归快排的数组大小小于3的时候,只能直接排序,就是几个简单的判断语句,这是可以再优化的
* @author:Gii
* @time:2017年4月3日 下午5:21:18
*/
public class QuickSort {
private static int[] arr = new int[] { 1, 2, 5, 3, 5, 7, 2, 4, 7, 1, 3, 42, 7, 233, 234, 67, 4, 3 };
public static void main(String[] args) {
// partition(0,7,4);
recSort(0, arr.length - 1);
for (int i : arr) {
System.out.print(i + " ");
}
}
public static void recSort(int begin, int end) {
if (end - begin < 3) {
smallSort(begin, end);
return;
}
int base = getBaseAndSort(begin, end);
int mid = partition(begin, end, base);
recSort(mid + 1, end);
recSort(begin, mid - 1);
}
private static void smallSort(int begin, int end) {
if (begin == end) {
return;
}
int mid = (begin + end) / 2;
if (arr[begin] > arr[end]) {
swap(begin, end);
}
if (arr[begin] > arr[mid]) {
swap(begin, mid);
}
if (arr[mid] > arr[end]) {
swap(mid, end);
}
}
private static int partition(int begin, int end, int base) {
int leftPoint = begin;
int rightPoint = end - 1;
// 1 8 1 4 5 2 6 4 8
// 1 4 1 4 2 8 6 8 5
while (true) {
while (arr[++leftPoint] < base);
while (arr[--rightPoint] > base);
if (leftPoint >= rightPoint) {
break;
} else {
swap(leftPoint, rightPoint);
}
}
swap(end - 1, leftPoint);
return leftPoint;
}
private static int getBaseAndSort(int begin, int end) {
int midPos = (begin + end) / 2;
if (arr[begin] > arr[midPos]) {
swap(begin, midPos);
}
if (arr[begin] > arr[end]) {
swap(begin, end);
}
if (arr[midPos] > arr[end]) {
swap(midPos, end);
}
swap(midPos, end - 1);
return arr[end - 1];
}
private static void swap(int a, int b) {
int tmp;
tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
}
}
简单改进的快排算法——含代码
最新推荐文章于 2024-08-25 17:42:15 发布