快速排序

踏踏实实积累,不要浮躁

 

(1):快排应该是工程上使用最多的一种算法了,时间复杂度O(nlogn) 不稳定,原地的排序算法

思想:利用递归依次找到数组最后一个元素在排序后的位置,

package sort;

import edu.princeton.cs.algs4.StdRandom;
import tools.Util;


public class quickSort {

    public static void sort(int[] arr){
        // 将原本的数组打乱,消除对输入的依赖  保持随机性
        StdRandom.shuffle(arr);
        sort(arr,0,arr.length - 1);
    }

    public static void sort(int[] arr,int low,int high){
        if(high <= low){
            return;
        }
        int j = partition(arr,low,high);
        sort(arr,low,j-1);
        sort(arr,j+1,high);
    }

    private static int partition(int[] arr, int low, int high) {
        int compar = arr[high];
        int left = low - 1;  // 先减一是为了后面格式统一++left 和 --right
        int right = high ;
        while (true){
            while (arr[++left] < compar){
                if(left == high){
                    break;
                }
            }
            while (arr[--right] > compar){
                if (right == low){
                    break;
                }
            }
            if(left >= right){
                break;
            }
            Util.swap(arr,left,right);
        }
        Util.swap(arr,left,high); // 这边进行交换只能用 left 
        return left;
    }

    public static void main(String[] args) {
        int[] arr = {3,2,6,4,9,1,5,99,100,35,45,100,234,5454,656,654,67,657,6,76,546,54,53,34,2};
        sort(arr);
        Util.println(arr);
    }


}

说明:

1:StdRandom.shuffle(arr);  是为了消除 对输入数组的依赖,保证数据随机性

2:下面的代码是对 快排的过程做的过程抽象,让代码看起来更直观,注意sort(arr,low,j-1)和sort(arr,j+1,high)不能写j这样会导致堆栈溢出死递归

if(high <= low){
    return;
}
int j = partition(arr,low,high);
sort(arr,low,j-1);
sort(arr,j+1,high);

3:重点在原地partition函数  思想懂了其实代码也很简单

 

(2):快速排序优化 思路

1:在数据量比较小的时候切换成插入排序,小数据量的表现上插入排序比快速排序快

2:用三向切分快速排序,考虑了重复元素的情况在含有大量重复元素的数据集中性能有较大的提升,比归并排序性能要好

思想:使用三个指针 lt , i ,gt 初始时 lt 和 i 相等,compar取值arr[low]然后进行如下规则的交换元素

1:arr[i] < compar 时 交换 arr[lt] 和 arr[i] 同时 lt 和 i 都加1

2:arr[i] > compar 时 swap(arr,i,gt--) 交换i位置和gt位置元素的值 同时将gt值减1

3:当arr[i] = compar 时 i ++ 继续进行如上循环 

 

public class quickSort2 {

    public static void sort(int[] arr,int low,int high){
        if(low >= high){
            return;
        }
        int lt = low;
        int i = low + 1;
        int gt = high;
        int compar = arr[low];
        while (i <= gt){
            if(arr[i] < compar){
                Util.swap(arr,i++,lt++);
            }else if(arr[i] > compar){
                Util.swap(arr,i,gt--); // 注意这边是 i
            }else {
                i++;
            }
        }
        sort(arr,low,lt -1);
        sort(arr,gt+1,high);
    }

    public static void main(String[] args) {
        int[] arr = {2,1,5,3,3,1,7,6,6,10};
        sort(arr,0,arr.length - 1);
        Util.println(arr);
    }
}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值