Java快速排序

本文详细介绍了快速排序算法的工作原理,包括选取基准数、分区过程、交换操作以及递归实现。通过实例演示了如何对给定数组进行快速排序,展示了其高效性和特点。
/**
 * Created with IntelliJ IDEA.
 * Description: 快速排序
 * 快速排序是冒泡排序的改进版,是目前已知的最快的排序方法。
 *
 * 该排序算法的基本思想是:
 *
 * 1.先从数列中取出一个数作为基准数。
 *
 * 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
 *
 * 3.再对左右区间重复第二步,直到各区间只有一个数。
 *
 * 优点:极快,数据移动少;
 *
 * 缺点:不稳定。
 *
 * 算法实现
 *
 * 假设我们现在要对{5,7,2,1,9,10,4,6,3,8}这个数组进行快速排序,我们应该怎么怎么做呢?
 *
 * 1.立Flag
 * Flag就是我们之前提到的基准数,为了将数据分区,立Flag是第一步也是最关键的一步。在这里我们将数组的第一个数设为基准数。
 *
 * 2.探测
 * 对于{5,7,6,1,9,10,4,2,3,8}这个数组,第一次排序我们的Flag是5,我们分别从数组的左右两端开始“探测”。
 *
 * 我们定义i指向数组的最左端,定义j指向数组的最右端。首先将j向左移,直到j指向的数小于5;再将i向右移,直到i指向的数大于5。最终i指向7,j指向3。
 *
 * 3.交换
 * 将3和7交换,数组变为{5,3,2,1,9,10,4,6,7,8}。第一次交换结束。
 *
 * 接下来继续探测、交换,探测、交换…
 *
 * 4.Flag落位
 * 第二次交换结束后数组变为{5,3,2,1,4,10,9,6,7,8}。
 *
 *
 * j指向9的位置,i指向4的位置,j继续向左移动,直到i的位置才找到小于5的值。
 *
 * 此时i=j,我们只需将Flag落在这个位置:将5和4的值交换。数组变为{4,3,2,1,5,10,9,6,7,8}。
 *
 * 至此,5这个Flag完成了它的历史使命,第一轮交换结束。
 * 在这里插入图片描述
 * 数组被划分为两个区,Flag左边是小于Flag的{4,3,2,1},Flag右边是大于Flag的{10,9,6,7,8}。
 * 在这里插入图片描述
 *
 * 5.递归
 * 我们再分别对这两个区进行第二轮交换,交换结果是{1,3,2,4}和{8,9,6,7,10}
 *
 * 对于{1,3,2}和{8,9,6,7}重复进行以上操作,直至得到不能拆解的单个数字,排序完成!
 *
 * @PackageName com.feixiang.platform.stu.math.sorting
 * @Author: ldwtxwhspring
 * @Date: 2020-05-19 上午5:12
 * @Version: 1.0
 */
public class QuickSort {

    /**
     * 内部引用方法,实现数组转字符串,达到toString效果,类同重写tostring
     * */
    private static String arraytoString(int[] objects){
        StringBuilder sb = new StringBuilder();
        sb.append("[ ");
        for(Object o:objects){
            sb.append(String.valueOf(o)).append(",");
        }
        //删除多余追加的,
        sb.deleteCharAt(sb.length()-1);
        sb.append(" ]");
        return sb.toString();
    }

    /**
     * 内部引用方法,断言,判断数组是否为空
     * */
    private static boolean isNullorEmpty(Object o){
        if(o instanceof Object[]){
            Object[] object = (Object[]) o;
            if (object.length == 0) {
                return true;
            }
            boolean empty = true;
            for (int i = 0; i < object.length; i++) {
                if (!isNullorEmpty(object[i])) {
                    empty = false;
                    break;
                }
            }
            return empty;
        }
        return false;
    }

    /**
     * 快排递归算法
     * @param array [array]
     * @return void
     * @author dwli
     * @date 2017/5/19 下午6:40
     */
    public static void quickSort(int[] array){

        if(isNullorEmpty(array)){
            return ;
        }
        sort(array,0,array.length-1);
    }

    public static void sort(int[] array,int left,int right){
        if(left>right) {
            return;
        }
        int base = array[left];
        int i = left;
        int j = right;
        while (i < j){
            // 先从右边开始往左找,直到找到比base值小的数
            while (array[j] <= base && i < j){
                j--;
            }
             // 再从左往右边找,直到找到比base值大的数
            while (array[i] >= base && i < j){
                i++;
            }
            // 上面的循环结束表示找到了位置或者(i>=j)了,交换两个数在数组中的位置
            if(i < j){
                int temp = array[j];
                array[j] =array[i];
                array[i] = temp;
            }
        }

        //基准值归位
        array[left] = array[i];
        array[i] = base;

        // 分治左递归
        sort(array, left, j - 1);
        // 分治右递归
        sort(array, j + 1, right);

    }

    public static void main(String[] args) {
        int[] array = new int[]{3,6,4,1,9,12,3,5};
        quickSort(array);
        System.out.println(arraytoString(array));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ldwtxwh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值