快速排序

数组排序——快速排序

一、一般的快速排序:

思路:

1、选择一个基准值,

2、比较数组中的元素,比基准值小的放入基准值的左边,比基准值大的放入基准 值的右边

3、递归的进行第二步,分别对左边和右边进行排序 

代码 :

public static int[] quickSort(int[] a, int l,int r){
    if(l >= r){
        return a;
    }
    int i = l;
    int j = r;
    //选取基准值
    int k = a[l];
    while(i < j){
        //从右边开始找到第一个小于k的元素,并把它放到左边去
        while(i < j && a[j] >= k){
            j--;
        }
        if(i < j){
            a[i] = a[j];
            i++;
        }
        //从左边开始找到第一个大于k的元素,并把它放到右边去
        while(i < j && a[i] < k){
            i++;
        }
        if(i < j){
            a[j] = a[i]
            j--;
        }
    }
    //经过上面的处理;随着i的位置的变化,k的位置应该变化到i处
    a[i] = k;
    //对左子数组,排序
    quickSort(a, l, i-1);
    //对右子数组,排序
    quickSort(a, i+1, r);
    return a;    
}

上面这一种排序方法,当数组中的重复元素较多的时候,虽然效率尚可,但是还是有优化空间的

优化的时候,基于一个事实,重复的元素是不需要进行排序的,上面的这种方式,会让重复的元素进入左右子数组中进行排序

寻找一种方法,不要让k的重复元素进入左右子数组

二、利用三向切分法

思路:

1、维护三个指针:lt    i    gt ,   选中基准值 k

2、l:是数组的左边界,r:是数组的右边界,

让 l ~ lt-1区间的元素都小于k ; lt ~ i-1 区间全是等于k的元素;i ~ gt :是不确定的元素,需要处理的元素;gt +1 ~ r 全是大于的k的元素,

3、处理过程:

  • a[i] > k ,那就交换a[gt] 和a[i]的位置 gt--
  • a[i] < k ,那就交换a[lt] 和a[i]的位置 lt ++
  • a[i]=k ,说明需要缩小i ~ gt的空间, i++ :慢慢的变成=k的空间,即lt+1 ~ gt-1

切分过程,如图:

 

 代码:

public static int[] quickSortThreeWay(int[] a,int l ,int r){
    if(l >= r){
        return a;
    }
    int lt = l;
    int i = l + 1;
    int gt = r;
    int k = a[l];
    while(i <= gt){
        if(a[i] > k){
            int tm = a[gt];
            a[gt] = a[i];
            a[i] = tm;
            gt--;
        }else if(a[i] < k){
            int tm = a[lt];
            a[lt] = a[i];
            a[i] = tm;
            lt++;
        }else{
            i++
        }
    }
    quickSortThreeWay(a,l lt - 1);
    quickSortThreeWay(a,gt + 1,r);
    return a;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值