数数1234

自娱自乐 欢迎访问:http://blog.liuyao.top

算法-快速排序及相关问题

快速排序及相关问题

1. 快速排序基础版

package com.liuyao.sort;

import com.liuyao.utils.SortHelper;

/**
 * Created By liuyao on 2018/4/13 22:09.
 */
public class QuickSort {
    private QuickSort(){}

    private static int partition(Comparable[] arr,int l,int r){
       Comparable v=arr[l];// 哨兵元素
       int j=l; //j初始为l,表示比哨兵小的元素个数为0
        for (int i = l+1; i <= r; i++) {
            if (arr[i].compareTo(v)<0){
                j++; //找到比哨兵小的所有元素的最后的一个位置。
                swap(arr,j,i);  //交换,将比哨兵大的元素放到后面来
            }
        }
        swap(arr,l,j); //将哨兵和比它小的最后一个元素交换位置。
        return j;
    }

    private static void sort(Comparable[] arr,int l,int r){
        if (l>=r){
            return;
        }
        int p=partition(arr,l,r);
        sort(arr,1,p-1);
        sort(arr,p+1,r);
    }

    public static void sort(Comparable[] arr){
        int n=arr.length;
        sort(arr,0,n-1);
    }

    public static void swap(Object[] arr,int i,int j){
        Object temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }

    public static void main(String[] args) {
        Integer[] a={2,3,6,8,1,4,5,7};
        new QuickSort().sort(a);
        SortHelper.print(a);
    }
}

2. 快速排序-哨兵随机

对于存在大部分有序数组,哨兵选择通过随机的方式,而不是默认选择第一个

package com.liuyao.sort;

import com.liuyao.utils.SortHelper;

/**
 * Created By liuyao on 2018/4/15 18:13.
 */
public class QuickSort2 {
    private QuickSort2(){

    }

    private static int partition(Comparable[] arr,int l,int r){
//        随机在arr[l...r]的范围中,选择一个数值作为标定点
        swap(arr,l, (int) ((Math.random()*(r-l+1))+l));
        Comparable v=arr[l];
        int j=l;
        for (int i = l+1; i <=r ; i++) {
            if (arr[i].compareTo(v)<0){
                j++;
                swap(arr,j,i);
            }
        }
        swap(arr,l,j);
        return j;
    }

    public static void sort(Comparable[] arr,int l,int r){
//        对于小规模数组,采用插入排序
//        if (r-l<=15){
//            new Insertion().sort(arr,l,r);
//        }

        if (l>=r){
            return;
        }
        int p=partition(arr,l,r);
        sort(arr,l,p-1);
        sort(arr,p+1,r);
    }

    private static void sort(Comparable[] arr){
        sort(arr,0,arr.length-1);
    }

    private static void swap(Object[] arr,int i,int j){
        Object t=arr[i];
        arr[i]=arr[j];
        arr[j]=t;
    }

    public static void main(String[] args) {
        Integer[] a={2,3,6,8,1,4,5,7};
        new QuickSort2().sort(a);
        SortHelper.print(a);
    }
}

3. 快速排序-2路排序

二路快排

package com.liuyao.sort;

import com.liuyao.utils.SortHelper;

/**
 * Created By liuyao on 2018/4/15 18:26.
 */
public class QuickSort3 {
    private QuickSort3() {

    }

    private static int partition(Comparable[] arr, int l, int r) {
        swap(arr, l, (int) (Math.random() * (r - l + 1)) + l);

        Comparable v = arr[l];

        int i = l + 1, j = r;

        while (true) {
//            当从前向后遇到大于等于v的数就停止
            while (i <= r && arr[i].compareTo(v) < 0) {
                i++;
            }

//            当从后向前遇到小于等于v的数就停止

            while (j >= l + 1 && arr[j].compareTo(v) > 0) {
                j--;
            }

            if (i > j) {
                break;
            }
//            前后交换
            swap(arr, i, j);
            i++;
            j--;
        }

        swap(arr, l, j);
        return j;
    }

    private static void sort(Comparable[] arr, int l, int r) {
//        if (r-l<=15){
//            new Insertion().sort(arr,l,r);
//        }

        if (l >= r) {
            return;
        }
        int p = partition(arr, l, r);
        sort(arr, 0, p - 1);
        sort(arr, p + 1, r);
    }

    private static void sort(Comparable[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    private static void swap(Object[] arr, int i, int j) {
        Object t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }

    public static void main(String[] args) {
        Integer[] a = {2, 3, 6, 8, 1, 4, 5, 7};
        new QuickSort3().sort(a);
        SortHelper.print(a);
    }
}

4. 快速排序-三路排序

package com.liuyao.sort;

import com.liuyao.utils.SortHelper;

/**
 * Created By liuyao on 2018/4/15 20:20.
 */
public class QuickSort3Ways {
    private QuickSort3Ways() {
    }

    public static void sort(Comparable[] arr, int l, int r) {
        if (r - l <= 15) {
            new Insertion().sort(arr, l, r);
            return;
        }
        swap(arr, l, (int) ((Math.random() * (r - l + 1)) + l));

        Comparable v = arr[l];
        int lt = l;   //arr[l+1...lt]<v
        int gt = r + 1; //arr[gt...r]>v
        int i = l + 1;  //arr[lt+1...i) == v

        while (i < gt) {
            if (arr[i].compareTo(v) < 0) {
                swap(arr, i, lt + 1);
                i++;
                lt++;
            } else if (arr[i].compareTo(v) > 0) {
                swap(arr, i, gt - 1);
                gt--;
            } else {
                i++;
            }
            swap(arr, l, lt);
            sort(arr, l, lt - 1);
            sort(arr, gt, r);
        }

    }

    public static void sort(Comparable[] arr) {

        int n = arr.length;
        sort(arr, 0, n - 1);
    }

    private static void swap(Object[] arr, int i, int j) {
        Object t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }

    public static void main(String[] args) {
        Integer[] a = {2, 3, 6, 8, 1, 4, 5, 7};
        new QuickSort3Ways().sort(a);
        SortHelper.print(a);
    }
}

5. 数组中第n大的数

6. 数组中的逆序对个数

主要是利用归并排序,比较,统计

package com.liuyao.sort;

import com.liuyao.utils.SortHelper;

import java.util.Arrays;

/**
 * Created By liuyao on 2018/4/15 21:18.
 */
public class InversionCount {
    private InversionCount(){}

    private static long merge(Comparable[] arr,int l,int mid,int r){
        Comparable[] aux= Arrays.copyOfRange(arr,l,r+1);

//        初始化逆序对数个数为0L
        long res=0L;

//        初始化时,i指向左半边起始索引位置l,j指向右半边起始索引位置mid+1
        int i=l,j=mid+1;

        for (int k = l; k <=r ; k++) {

//            左半边已经全部处理完
            if (i >mid){
                arr[k]=aux[j-l];
                j++;
            } else if (j >r){  //右半边已经全部处理完
                arr[k]=aux[i-l];
                i++;
            } else if (aux[i-l].compareTo(aux[j-l])<=0){ //左边元素比右边小,将左边元素放入
                arr[k]=aux[i-l];
                i++;
            }else {   //否者右边的元素比左边的小,存在逆序对
                arr[k]=aux[j-l];
                j++;
                //此时这个元素和左半边部分的所有为处理的元素构成逆序对
                // 左半边部分此时为处理的元素个数为mid-j+l
                res+=(mid-i+l);
            }
        }
        return res;
    }

    private static long solve(Comparable[] arr,int l,int r){
        if (l>=r){
            return 0L;
        }
        int mid=l+(r-l)/2;
// 求出 arr[l...mid] 范围的逆序数
        long res1=solve(arr,l,mid);
// 求出 arr[mid+1...r] 范围的逆序数
        long res2=solve(arr,mid+1,r);

        return res1+res2+merge(arr,l,mid,r);
    }

    public static long solve(Comparable[] arr){
        return solve(arr,0,arr.length-1);
    }

    public static void main(String[] args) {
        Integer[] a = {2, 3, 6, 8, 1, 4, 5, 7};
        System.out.println(new InversionCount().solve(a));
    }
}
阅读更多
版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/l2580258/article/details/79978432
个人分类: 算法
想对作者说点什么? 我来说一句

快速排序Demo

2016年05月03日 19KB 下载

快速排序c++源代码

2010年09月05日 458KB 下载

没有更多推荐了,返回首页

不良信息举报

算法-快速排序及相关问题

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭