快速排序

快速排序

快速排序的大致思想是:对于一个组数据,先选出一个标识位,把比这个标识数据小的数据全部放在标识位前,其他的比标志数据大的放在标识位后面;然后不断重复这个过程同时缩小范围,最终数据就是一组有序的数据.

快速排序的范围变化和归并排序很像,只是归并是由小到大不断合并,快排是由大到小不断分割.

同样也分为两个实现过程

  • 分割一组数据.
  • 选择标识位,改变数据位置.

分割一组数据的实现

    /**
     * @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;
    }

}

posted @ 2020-05-13 20:44  continued258  阅读(139)  评论(0)    收藏  举报