Java算法:快速排序

一、快速排序

快速排序算法是对冒泡排序算法的一种改进算法,在当前所有内部排序算法中,快速排序算法被认为是最好的排序算法之一。

基本思想:通过一趟排序将待排记录分隔成独立的左右两部分,左边的子序列中所有数据都比右边子序列中的数据小,然后对左右两个子序列继续进行排序,直到整个序列有序。

快速排序使用**分而治之 divide and conquer(D&C)**法来把一个串(list)分为两个子串(sub-lists)

二、快速排序步骤

  1. 从数组中按照一定的规则选择一个元素作为基准值
  2. 把基准值与其他元素进行比较,将元素分成两部分,把所有比基准值小的值放在左侧,所有比基准值大的放在右侧。即进行区域划分
  3. 通过递归上述操作,再次将左右两区域进行区域划分,完成排序.

三、java实现快速排序

复制代码
    public static void main(String[] args) {
        //调用数据
        Integer[] datas =getData();
        System.out.println("排序前的数组:"+Arrays.toString(datas));
        sort(datas, 0, datas.length-1);
        System.out.println("排序后的数组:"+ Arrays.toString(datas));

    }



    /**
     * (1) 生成1-100范围的随机数10个
     */
    private static Integer[] getData() {
        Set<Integer> sets = new HashSet<>();
        Random random = new Random();
        while (true) {
            //生成1-100的随机数
            int ran = random.nextInt(100) + 1;
            //添加
            sets.add(ran);
            //判断生成10个数据
            if (sets.size() >= 10) {
                break;
            }
        }
        // 将Set转换成数组
        Integer[] arr = sets.toArray(new Integer[sets.size()]);
        return arr;
    }

    /**
     * @param arrs   数组无序
     * @param before (子)序列最前面的索引
     * @param after  (子)序列最后面的索引
     */
    public static void sort(Integer[] arrs, int before, int after) {
        int left = before; //左边
        int right = after; //右边
        int key = arrs[before]; //基准值
        //循环比较
        while (right > left) {
            //(1)从后往前比较
            while (right > left && arrs[right] >= key)  //如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
                right--;
            //判断有比关键值小的交换位置
            if (arrs[right] <= key) {
                int temp = arrs[right];
                arrs[right] = arrs[left];
                arrs[left] = temp;
            }
            //(2)从前往后比较
            while (right > left && arrs[left] <= key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
                left++;
            //判断有比关键值大的交换位置
            if (arrs[left] >= key) {
                int temp = arrs[left];
                arrs[left] = arrs[right];
                arrs[right] = temp;
            }
        }
        // 此时第一次循环比较结束,关键值的位置已经确定了。
        // 左边的值都比关键值小,右边的值都比关键值大,
        // 但是两边的顺序还有可能是不一样的,进行下面的递归调用
        //递归关键值左右二边的子序列
        if (left > before) {
            //递归左边子序列
            sort(arrs, before, left - 1);

        }
        if (right < after) {
            //递归右边子序列
            sort(arrs, right + 1, after);
        }
    }
}

四、性能分析

**优点:**效率高,时间复杂度平均为O(nlogn),快速排序是最快的排序算法,耗费的资源少,最佳情况下,空间复杂度为O(logn),每一次都平分数组的情况,代码较为简单。

缺点:不稳定,初始序列有序或基本有序时,时间复杂度降为O(n^2)。

相关推荐
Wang's Blog6 小时前
Java 项目实战: 外卖平台优化-Nginx配置文件结构与块层级
java·开发语言·nginx
\光辉岁月/7 小时前
5.java-数组
java·开发语言
谢亮_vipxieliang7 小时前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot
郑州光合科技余经理8 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
2601_962071578 小时前
类变量和全局变量的生命周期有什么区别?
java·开发语言·jvm
code2cat8 小时前
Java进阶篇之AtomicReference:一次替换引用,读到一份完整状态
java·并发编程·不可变对象·atomicreference
专业程序开发源8 小时前
springboot简历管理系统81389-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计
Wang's Blog8 小时前
Java 项目实战: 外卖平台优化-前后端分离开发模式与工程拆分
java·开发语言
h_a_o777oah9 小时前
【树论】树链剖分:将树形结构转化为线性结构以处理树上路径问题(洛谷 P3384 附C++代码模板)
数据结构·算法·线段树·acm·树链剖分·树论·重链剖分
HEJOO99 小时前
指针的算术运算详解
java·数据结构·算法