zoukankan      html  css  js  c++  java
  • 排序算法-快速排序

    快速排序的思想:

      先以一个元素作为标准,找到这个元素的位置,这个位置前的数据都比这个元素小,这个元素后的数据都比这个元素大。

      下面代码适用场景,没有大量重复元素的数据。

      由于比较懒,盗个图吧:

      

    第一版代码如下:

    //快速排序
    public void quickSort(Integer[] arr,int n){
    //递归函数入口
    __quickSort(arr,0,n-1);
    }
    public void __quickSort(Integer[] arr,int l,int r){
    //第一次优化,小于15,直接插入排序,省去递归过程
    if(r-l<=15) {__meargeInsertSort(arr,l,r);return ;}
    //找到分区插入的位置,
    int p = __quickSortPartition(arr,l,r);
    //递归快排
    __quickSort(arr,l,p-1);
    __quickSort(arr,p+1,r);
    }
    public Integer __quickSortPartition(Integer[] arr,int l,int r){
    //找到随机种子,排除已经是顺序数组所带来的性能影响
    Random random = new Random();
    int seedid = random.nextInt(r-l+1)+l;
    int v = arr[l];
    arr[l] = arr[seedid];
    arr[seedid] = v;

    //arr[l+1...j]<v arr[j+1...r]>v
    v = arr[l];
    int i=l+1,j=l;
    for(;i<=r;i++){
    if(arr[i]<v) {
    int temp = arr[i];
    arr[i] = arr[j+1];
    arr[j+1]=temp;
    j++;
    }
    }
    return j;
    }

    第二版代码:
    使用场景,有大量重复的数据的时候,没有重复数据的时候,上述代码会稍微好一点点,但总体来说,处理速度在一个恒定的范围内。
    //快速排序---去除重复
    public void quickSort2(Integer[] arr,int n){
    __quickSort2(arr,0,n-1);
    }
    public void __quickSort2(Integer[] arr,int l,int r){
    if(r-l<=15){__meargeInsertSort(arr,l,r); return;}
    int p=__quickSortPartition2(arr,l,r);
    __quickSort2(arr,l,p-1);
    __quickSort2(arr,p+1,r);
    }
    public int __quickSortPartition2(Integer[] arr,int l,int r){
    Random random = new Random();
    int selectid = random.nextInt(r-l+1)+l;
    int v = arr[selectid];
    arr[selectid] = arr[l];
    arr[l] = v;

    int i=l+1,j=r;
    while(true){
    while(arr[j]>=v && j>l) j--;
    while(arr[i]<=v && i<=r) i++;
    if(i>j) break;
    int t =arr[j];
    arr[j] = arr[i];
    arr[i]=t;
    j--;
    i++;
    }
    return j;

    }
    第三版,三路排序,不再讨论。

    代码如下:

    //快速排序--三路
    public void quickSort3Ways(Integer[] arr,int n){
    __quickSort3Ways(arr,0,n-1);
    }
    public void __quickSort3Ways(Integer[] arr,int l,int r){
    //优化
    if(r-l<=15){__meargeInsertSort(arr,l,r);return;}
    //随机种子,偷懒了
    int v =arr[l];
    //i是进行循环,gt是大于v的数组,lt是小于v的边界,lt-gt是等于v
    int i=l+1,gt=r+1,lt=l;
    for(;i<gt;i++){
    if(arr[i]<v)
    {
    int t = arr[i];
    arr[i] = arr[lt+1];
    arr[lt+1]=t;
    lt++;
    }
    else if(arr[i]>v){
    int t=arr[i];
    arr[i] = arr[gt-1];
    arr[gt-1] =t;
    gt--;
    }
    }
    //交换lt和l的值
    int t = arr[lt];
    arr[lt] = arr[l];
    arr[l] = t;
    //lt-1,因为lt最后和t进行了互换
    __quickSort3Ways(arr,l,lt-1);
    __quickSort3Ways(arr,gt,r);
    }
  • 相关阅读:
    【Android】Android如何实现手机震动
    【Android】详解Android的menu菜单
    【Smali】Smali文件的动态调试
    【C#】C#项目如何获得项目的根目录
    【Android】Android如何对APK签名
    【Android】Android如何对APK反编译
    【SqlServer】在SqlServer中把数据导入导出为Excel文件
    【C#】解析C#中JSON.NET的使用
    【C#】浅析C#中的日期处理
    TCP与UDP传输协议
  • 原文地址:https://www.cnblogs.com/wind-man/p/10828886.html
Copyright © 2011-2022 走看看