快速排序

一、Hoare


(一)算法简介

选取第一个元素作为基准点(可以随机选取),将剩下元素与基准点进行比较,

比基准点大的放在右边,比基准点小的放在左边, 得到左子表和右子表,递归调用本函数;


1491599-20191019112640308-1436008740.jpg


(二)代码:


/**
 * @title: quickSort
 * @description: 快速排序: 选取第一个元素作为基准点(可以随机选取),将剩下元素与基准点进行比较,
 *               比基准点大的放在右边,比基准点小的放在左边, 得到左子表和右子表,递归调用本函数;
 * @date: Jun 10, 2019 8:19:59 PM
 * @param value
 * @param begin 开始下标
 * @param end   结束下标
 * @throws:
 * */
public static void quickSort(int[] value, int begin, int end) {
        if (begin >= 0 && begin < end && end < value.length) {
            int i = begin, j = end;
            int center = value[i];// 中心元素

            while (i != j) {
                while (i < j && center < value[j]) {
                    j--;
                }
                if (i < j)// 跳出循环也有可能时因为i=j,所以这里要判断一下
                    value[i++] = value[j];

                while (i < j && center > value[i]) {
                    i++;
                }
                if (i < j)
                    value[j--] = value[i];
            }
            value[i] = center;// 中心元素到达最终位置

            quickSort(value, begin, i - 1);
            quickSort(value, i + 1, end);
        }
    }


(三)注解:

  • 简化步骤:当需要移动时,不用交换swap两个元素。

记录下刚开始比较的i下标元素(也就是基准点),需要移动的元素直接覆盖到移动到去向位置,在一轮比较结束后(i==j),i(或J)下标位置赋值 基准点,中心元素到达最终位置。

  • j向前逼近,当j下标元素比基准点小时,将j下标元素赋值到i位置,i下标++;

    i向后逼近,当i下标元素比基准点大时,将i下标元素赋值到j位置,j下标++;

    重复以上两步,直到i==j为止跳出循环,基准点赋值到i(或j)位置。

  • j向前逼近 和i向前逼近 两个循环不能倒过来,不然i位置一开始就和自己(基准点)比较大小了。


(四)排序是否稳定

取决于比较时此处取不取等号

1491599-20191019112847396-459472789.png


示例:

1491599-20191019112920814-1108524785.jpg


二、Lomuto

(一)代码:


1.Lomuto

package Sort;

/**
 * Lomuto算法,用第一个元素作为中轴,划分数组: 数组划分为3段,一段为<p的元素,一段为>=p的元素,还有一段为未处理的元素, 算法开始前,前两段为空。
 * L为数组首个元素的下标,R为数组最后元素的下标,s指向<p段的最后一个元素,
 * i向后扫描数组(指向未处理段的第一个元素),初值为L+1。p为数组首个元素A[L]。
 * 在遍历中,当A[i]<p,s加1,再交换A[i]和A[s];当A[i]>=p,只要i加1,相当于扩大了>=p段,同时缩小未处理段。
 * 当未处理段为空时,交换p(中轴)和A[s](<p段的最后一个元素),算法结束。
 */
public class Lomuto {

    public static int LomutoPartition(int[] arrays,int l,int h) {
        int p = arrays[l];// 中轴:指向第一个元素
        int s = l;// 初值为第一个元素,指向<p段的最后一个元素
        for (int i = l+1; i <= h; i++)
            if (arrays[i] < p) {
                s = s + 1;
                swap(arrays, s, i);
            }
            
        swap(arrays, s, l);//交换 中轴 和 <p段的最后一个元素
        
        return s;
    }

    /**
     * 交换两个数
     */
    private static void swap(int[] arrays, int s, int i) {
        int temp;
        temp = arrays[s];
        arrays[s] = arrays[i];
        arrays[i] = temp;
    }


}


2.quickSortS

/**
     * 快速排序:运用Lomuto
     */
    public static void quickSort2(int[] value, int begin, int end) {
        if (begin >= 0 && begin < end && end < value.length) {
            
            int p=Lomuto.LomutoPartition(value,begin,end);//中轴下标
//          System.out.println("中轴p="+p);
//          System.out.println(p);
            
            quickSort2(value, begin, p - 1);
            quickSort2(value, p + 1, end);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值