快速排序
快速排序
快速排序的大致思想是:对于一个组数据,先选出一个标识位,把比这个标识数据小的数据全部放在标识位前,其他的比标志数据大的放在标识位后面;然后不断重复这个过程同时缩小范围,最终数据就是一组有序的数据.
快速排序的范围变化和归并排序很像,只是归并是由小到大不断合并,快排是由大到小不断分割.
同样也分为两个实现过程
- 分割一组数据.
- 选择标识位,改变数据位置.
分割一组数据的实现
/**
* @param data 存储数据的数组
* @param begin 划分的开始位置
* @param end 划分的结束位置
* 表述均是[begin,end)左闭右开
*/
public static void sort(int[] data, int begin, int end) {
if (end - begin > 1) {
int mid = fun(data, begin, end);//选择标识位,改变数据位置的方法.
sort(data, begin, mid);
sort(data, mid, end);
}
}
选择标识位,改变数据位置的实现
- 虽然描述中是:选出一个标识位,把比这个标识数据小的数据全部放在标识位前,其他的比标志数据大的放在标识位后面.但是实现过程并不需要像选择排序那样操作.
- 一般实现是:选择最后一位作为标志位,在数组左 右个有一个标记,先把左标记向右移动,如果遇到大于标识数据时停下移动右标记,如果右标记遇到小于标识数据时停下,之后左 右标记数据交换,直到左标记位置大于等于右标记位置.
/**
* @param data 存储数据的数组
* @param begin 划分的开始位置
* @param end 划分的结束位置
* @return 结束时标识位的位置
* 表述均是[begin,end)左闭右开
*/
public static int fun(int[] data, int begin, int end) {
int len = end - begin;
if (len == 2) {//如果数据长度只有2直接排序后返回
int min = Math.min(data[begin], data[begin + 1]);
int max = Math.max(data[begin], data[begin + 1]);
data[begin]=min;
data[begin+1]=max;
return begin + 1;
}
int left = begin;//左标记
int right = end - 2;//右标记
int flag = data[end - 1];//标志位
while (left < right) {
while (left <= end - 2 && data[left] <= flag) {//移动左标记
left++;
}
while (right >= begin && data[right] >= flag) {//移动右标记
right--;
}
if (left < right) {//交换数据位置
int temp = data[left];
data[left] = data[right];
data[right] = temp;
}
}
//结束时候,交换左标记的位置和标志位
int temp = data[left];
data[left] = flag;
data[end - 1] = temp;
return left;
}
示例
import java.util.Arrays;
import java.util.Random;
public class QuickSort {
public static void main(String[] args) {
int[] data = new int[100000];
Random random = new Random();
for (int i = 0; i < data.length; i++) {
data[i] = random.nextInt(Integer.MAX_VALUE);
}
long timeMillis = System.currentTimeMillis();
sort(data, 0, data.length);
System.out.println(System.currentTimeMillis()-timeMillis);
System.out.println(Arrays.toString(data));
}
public static void sort(int[] data, int begin, int end) {
if (end - begin > 1) {
int mid = fun(data, begin, end);
sort(data, begin, mid);
sort(data, mid, end);
}
}
public static int fun(int[] data, int begin, int end) {
int len = end - begin;
if (len == 2) {
int min = Math.min(data[begin], data[begin + 1]);
int max = Math.max(data[begin], data[begin + 1]);
data[begin]=min;
data[begin+1]=max;
return begin + 1;
}
int left = begin;
int right = end - 2;
int flag = data[end - 1];
while (left < right) {
while (left <= end - 2 && data[left] <= flag) {
left++;
}
while (right >= begin && data[right] >= flag) {
right--;
}
if (left < right) {
int temp = data[left];
data[left] = data[right];
data[right] = temp;
}
}
int temp = data[left];
data[left] = flag;
data[end - 1] = temp;
return left;
}
}

浙公网安备 33010602011771号