Day_46快速排序

news2024/12/23 13:34:21

目录

一. 关于快速排序思路的产生

二. 快速排序的实现

        1. 快速排序的实现

        2. 快速排序的效率分析

三. 快速排序的代码实现

        1. 快速排序

        2. 快速排序核心代码:

四. 代码展示

五. 数据测试

六. 总结


一. 关于快速排序思路的产生

        从现在开始,让我们假设需要被排好序的事物列表是一些需要按升序排列的数字(算法对任何其它对象列表和顺序都是一样的。)给定这样一个数字列表,怎么样尽可能快速的将这一串数字序列排列好呢?

        我们之前学习的算法——类似于冒泡,直接插入,希尔排序都是基于序列本身的,我们现在能否找一个利用分而治之和递归的思想来进行排序的算法呢?意思就是我能不能将序列分成几段,在这分好的小段中又分段,这样迭代进行下去,直到只剩下一个数字,最后再把这拍好的数字组合起来,那不就对序列排好序了吗?

        于是乎快速排序——被誉为是最好的排序算法之一诞生了。

分而治之和递归的思想

 

二. 快速排序的实现

        1. 快速排序的实现

        快速排序的基本思想是基于分治法的,在待排序表L[1...n]中任取一个元素pivot作为枢轴(或称基准),通过一趟排序将待排序表划分为独立的两个部分L[1...k-1]和L[k+1...n],使得L[1...k-1]中的所有元素小于pivot,L[k+1...n]中的所有元素大于或等于pivot,则pivot放在了其最终位置L(k)上,这个过程称为一次划分。然后分别递归的对两个子表重复上述过程,直到每部分内只有一个元素或为空为止,即所有元素放在了其最终位置上。

        一趟快速排序的过程是一个交替搜索和交换的过程,下面通过实例介绍:

         可以发现每一轮我们选定一个量作为分段的依据,接着分好的子段进行同样的操作,直到得到最终的结果。

        2. 快速排序的效率分析


        空间效率:由于快速排序是递归的,需要借助一个递归调用栈来保存每层递归调用的必要信息,其容量与调用的最大深度一致。最好情况下为O(log_{2}n);最坏情况下,因为要进行n-1次递归调用,所以栈的深度为O(n);平均情况下,栈的深度为O(log_{2}n)

         时间效率:快速排序的运行时间与划分是否对称有关,快速排序的最坏情况发生在两个区域分别为n-1个元素和0个元素时,这种最大限度的不对称性若发生在每层递归上,即对应于初始排序表基本有序或者基本逆序时,就得到最坏情况下的时间复杂度为O(n^{2});在最理想情况下,即枢轴量每次都做到最平衡的划分,得到的两个子问题的大小都不可能大于n/2,在这种情况下,快速排序的运行速度将大大提升,此时,时间复杂度为O(nlog_{2}n)。好的快速排序平均情况下的运行时间与其最佳情况下的运行时间很接近而不是接近其最坏情况下的运行时间。快速排序是所有内部排序算法中平均性能最优的排序算法。

        稳定性:在划分算法中,若右端区间有两个关键字相同,且均小于基准值的记录,则在交换到左端区间后,它们的相对位置发生了变化,即快速排序是一种不稳定的排序方法。

最好情况下
最坏情况下

         可以发现,每次枢轴量刚好取到能几乎平分字段时,效率最快,并且深度最低;若每次取到的枢轴量为最大(最小)值时,效率最低,并且深度最大。

三. 快速排序的代码实现

        1. 快速排序

        这部分代码不是核心,相当于确定一个排序的开头start和排序的结尾end。

    /**
     *********************
     * Quick sort.
     *********************
     */
    public void quickSort() {
        quickSortRecursive(0, length - 1);
    }// Of quickSort

        2. 快速排序核心代码:

        首先确定边界是否合法,若Start >= End直接结束调用。

        找到第一个枢轴量存在的位置,然后将两者互换位置,接着调入下一轮递归。(我觉得这些东西都很简单,按着代码来理解就好了,关键是理解背后的思想,接着用代码实现就可以了,代码的过程可能和人想的过程不一样,但是实现得到的最终结果是一样的)。

    /**
     *********************
     * Quick sort recursively.
     *
     * @param paraStart The start index.
     * @param paraEnd   The end index.
     *********************
     */
    public void quickSortRecursive(int paraStart, int paraEnd) {
        // Nothing to sort.
        if (paraStart >= paraEnd) {
            return;
        } // Of if

        int tempPivot = data[paraEnd].key;
        DataNode tempNodeForSwap;

        int tempLeft = paraStart;
        int tempRight = paraEnd - 1;

        // Find the position for the pivot.
        // At the same time move smaller elements to the left and bigger one to the
        // right.
        while (true) {
            while ((data[tempLeft].key < tempPivot) && (tempLeft < tempRight)) {
                tempLeft++;
            } // Of while

            while ((data[tempRight].key >= tempPivot) && (tempLeft < tempRight)) {
                tempRight--;
            } // Of while

            if (tempLeft < tempRight) {
                // Swap.
                System.out.println("Swapping " + tempLeft + " and " + tempRight);
                tempNodeForSwap = data[tempLeft];
                data[tempLeft] = data[tempRight];
                data[tempRight] = tempNodeForSwap;
            } else {
                break;
            } // Of if
        } // Of while

        // Swap
        if (data[tempLeft].key > tempPivot) {
            tempNodeForSwap = data[paraEnd];
            data[paraEnd] = data[tempLeft];
            data[tempLeft] = tempNodeForSwap;
        } else {
            tempLeft++;
        } // Of if

        System.out.print("From " + paraStart + " to " + paraEnd + ": ");
        System.out.println(this);

        quickSortRecursive(paraStart, tempLeft - 1);
        quickSortRecursive(tempLeft + 1, paraEnd);
    }// Of quickSortRecursive

四. 代码展示

        主类:

package Day_46;

import Day_41.DataArray;

public class demo1 {
    /**
     *********************
     * The entrance of the program.
     *
     * @param args Not used now.
     *********************
     */
    public static void main(String args[]) {
//        System.out.println("\r\n-------sequentialSearchTest-------");
        int []paraKeyArray;
        paraKeyArray=new int[]{11,2,3};
        String[] paraContentArray = new String[]{"121","21","324"};
        DataArray test=new DataArray(paraKeyArray,paraContentArray);

//        test.insertionSort();
//        System.out.println("Result\r\n" + test);
        test.quickSortTest();


    }// Of main
}

        调用类:


    /**
     *********************
     * Quick sort recursively.
     *
     * @param paraStart The start index.
     * @param paraEnd   The end index.
     *********************
     */
    public void quickSortRecursive(int paraStart, int paraEnd) {
        // Nothing to sort.
        if (paraStart >= paraEnd) {
            return;
        } // Of if

        int tempPivot = data[paraEnd].key;
        DataNode tempNodeForSwap;

        int tempLeft = paraStart;
        int tempRight = paraEnd - 1;

        // Find the position for the pivot.
        // At the same time move smaller elements to the left and bigger one to the
        // right.
        while (true) {
            while ((data[tempLeft].key < tempPivot) && (tempLeft < tempRight)) {
                tempLeft++;
            } // Of while

            while ((data[tempRight].key >= tempPivot) && (tempLeft < tempRight)) {
                tempRight--;
            } // Of while

            if (tempLeft < tempRight) {
                // Swap.
                System.out.println("Swapping " + tempLeft + " and " + tempRight);
                tempNodeForSwap = data[tempLeft];
                data[tempLeft] = data[tempRight];
                data[tempRight] = tempNodeForSwap;
            } else {
                break;
            } // Of if
        } // Of while

        // Swap
        if (data[tempLeft].key > tempPivot) {
            tempNodeForSwap = data[paraEnd];
            data[paraEnd] = data[tempLeft];
            data[tempLeft] = tempNodeForSwap;
        } else {
            tempLeft++;
        } // Of if

        System.out.print("From " + paraStart + " to " + paraEnd + ": ");
        System.out.println(this);

        quickSortRecursive(paraStart, tempLeft - 1);
        quickSortRecursive(tempLeft + 1, paraEnd);
    }// Of quickSortRecursive

    /**
     *********************
     * Quick sort.
     *********************
     */
    public void quickSort() {
        quickSortRecursive(0, length - 1);
    }// Of quickSort

    /**
     *********************
     * Test the method.
     *********************
     */
    public static void quickSortTest() {
        int[] tempUnsortedKeys = { 1, 3, 12, 10, 5, 7, 9 };
        String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
        DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

        System.out.println(tempDataArray);

        tempDataArray.quickSort();
        System.out.println("Result\r\n" + tempDataArray);
    }// Of quickSortTest

五. 数据测试

        运行得到的结果如图所示:

六. 总结

        这一部分的排序代码可能确实要比插入和冒泡难一点,但是我觉得可以接受,其实本质思想就一个——分而治之,根据从数组里面找到的枢轴量,把数组分成两个部分,再对这两个部分重复上述的操作,最后得到排序结果即可。不过这里我们可以发现有重复调用的情况出现,所以这里一定会有栈(递归)等方式的出现,一旦有这个递归出现就意味着需要额外空间来存储数据,所以这个快速排序算法并不是原地算法,需要额外的空间。这个所需空间的大小和排序调用层数有关(时间复杂度也和这个相关,具体的详见上文。)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/623972.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hive学习---7、企业级调优

1、企业级调优 1.1 计算资源配置 到此学习的计算环境为HIve on MR。计算资源的调整主要包括Yarn和MR。 1.1.1 Yarn资源配置 1、Yarn配置说明 需要调整的Yarn的参数均与CPU、内存等资源有关&#xff0c;核心配置参数如下&#xff1a; &#xff08;1&#xff09;yarn.nodeman…

Python 三局两胜小游戏

文章目录 1. 明确项目目标2. 分析过程&#xff0c;拆解项目3. 逐步执行 代码实现版本1&#xff1a;版本2&#xff1a;【格式化字符串 %】 1. 明确项目目标 今天且让我扮演一下产品经理的角色。我们此次要实现的需求是&#xff1a;人机PK小游戏。具体效果请参照下面的示意动图。…

OpenGL之VAO,VBO和EBO

一、BO&#xff08;Buffer Object&#xff0c;缓冲对象&#xff09; 缓冲对象是OpenGL管理的一段内存&#xff0c;为了与我们CPU的内存区分开&#xff0c;一般称OpenGL管理的内存为&#xff1a;显存。 显存&#xff0c;也就是显卡里的内存。显卡访问显存比较快&#xff0c;而Bu…

vue3 element-plus 暗黑模式(主题切换)简易版

暗黑模式是说明 暗黑模式是指在应用程序或操作系统中使用暗色背景和浅色文本的界面设计。与传统的亮色模式相比&#xff0c;暗黑模式具有以下特点&#xff1a; 减少眼部疲劳&#xff1a;使用暗色背景可以减少屏幕发出的蓝光&#xff0c;减轻长时间使用电子设备对眼睛的疲劳程度…

【算法与数据结构】707.、LeetCode设计链表

文章目录 一、题目二、设计链表三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、设计链表 思路分析&#xff1a;这里我将的成员函数放在类外实现了&#xff0c;这样链表类看起来更加简洁&#xff0c;方便大家…

mysql之uniquekey学习。

uniquekey就真的是唯一键了吗&#xff1f; 答案是不是的。可以允许多个重复null值的存在&#xff0c;版本5.73 CREATE TABLE student_uniq ( id int(11) DEFAULT NULL, name varchar(200) DEFAULT NULL, socre int(11) DEFAULT NULL, UNIQUE KEY s_uniq (socre,name) )…

【操作系统】Linux进阶必须掌握的进程、线程及调度算法~进程学习

Linux内核源代码中&#xff0c;进程的状态是用数字来表示的&#xff0c;为了弄明白正在运行的进程是什么意思&#xff0c;我们需要知道进程的不同状态。一个进程可以有几个状态&#xff08;在Linux内核里面&#xff0c;进程有时候也叫任务&#xff09; /* The task state arra…

【TA100】图形 2.6伽马(Gamma)校正

很好的视频 https://www.bilibili.com/video/BV15t411Y7cf/?spm_id_from333.788.b_636f6d6d656e74.96&vd_source6f3a5e0ac931d869aee3d7c9bb6847e0 一、Gamma校正 1.前言&#xff1a;颜色空间 ● 一些颜色空间的举例&#xff0c;&#xff08;具体参考2.1节内容&#xff0…

最大似然估计(MLE)VS 最大后验概率估计(MAP)

1、概率和统计是一个东西吗&#xff1f; 概率&#xff08;probabilty&#xff09;和统计&#xff08;statistics&#xff09;看似两个相近的概念&#xff0c;其实研究的问题刚好相反。 一句话总结&#xff1a;概率是已知模型和参数&#xff0c;推数据。统计是已知数据&#x…

普通学校计算机毕业生,从事网络安全行业可以吗?

如果你是普通大学、大专的计算机专业应届生&#xff0c;还在迷茫找工作&#xff0c;这篇内容希望你能认真看完&#xff0c;很可能会决定你的人生方向。 现在的高薪行业&#xff0c;除了明星就只能是程序员了。不信你问问身边的人想学哪个专业&#xff0c;他们肯定不假思索的说…

C++基础(三) —— 内存分配

文章目录 概念01 物理地址内存的分配与释放02 虚拟用户进程空间内存的分配与释放 03 allocator模板类04 new delete05 malloc free06 strcpy 与 memcpy 与 memsetstrcpymemcpymemset 概念 01 物理地址内存的分配与释放 主要采用链表结构 使用了一个名叫page的结构体管理物理…

基于nodejs实现text/event-stream简单应用案例,SSE

基于nodejs实现text/event-stream简单应用案例&#xff0c;SSE text/event-stream代码实现服务器端前端 效果 text/event-stream 是一种用于服务器向客户端推送事件的媒体类型&#xff08;Media Type&#xff09;。它是基于 HTTP 协议的一种流式传输技术&#xff0c;也被称为 …

揭秘新一代云数仓技术架构与最佳实践

从传统数仓到湖仓一体&#xff0c;历经三十多年发展&#xff0c;技术的浪潮快速迭代&#xff0c;以云原生数仓为中心的现代数据栈时代已然到来。 背后的核心的原因在于&#xff0c;企业正在加速走向数字化、智能化&#xff0c;对数据的应用也提出了全新要求&#xff0c;特别是对…

每日一练 | 华为认证真题练习Day55

1、RSTP协议配置BPDU中的Flag字段使用了哪些STP协议未使用的标志位&#xff1f;&#xff08;多选&#xff09; A. Agreement B. TCA C. TC D. Proposal 2、RSTP中Backup端口可以替换发生故障的根端口。 A. 对 B. 错 3、如下图所示的网络&#xff0c;在RouterA设备里面存在…

更适合中国打工人体质的报表工具,零代码自动生成老板满意模板!

“中国职场上大家公认最头疼的是什么&#xff1f;” “加班&#xff1f;裁员&#xff1f;薪资&#xff1f;” “一切的根源来源于哪&#xff1f;” “是因为做大大小小报表加班到深夜、是同事都在卷报表制作有人只能被动裁员&#xff0c;也是千篇一律的报表汇报决定了这职业…

FreeRTOS学习笔记(五)——应用开发(三)

文章目录 0x01 软件定时器应用场景定时器精度运作机制软件定时器控制模块函数接口xTimerCreate()prvInitialiseNewTimer()xTimerStart()xTimerGenericCommand()xTimerStartFromISR()xTimerStop()xTimerStopFromISR()xTimerDelete()软件定时器任务创建以及执行原理软件定时器实验…

如何优化档案库房管理?一招学会轻松提升效率

在现代企业运营中&#xff0c;档案库房扮演着重要的角色&#xff0c;承载着大量宝贵的纸质档案资料。这些档案包含着企业的历史、客户信息、法律文件等重要数据&#xff0c;对于企业的正常运转和决策制定至关重要。然而&#xff0c;传统的档案库房管理方式存在一系列的挑战和难…

深度刨析指针Advanced 1

作者主页&#xff1a;paper jie的博客_CSDN博客-C语言,算法详解领域博主 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《系统解析C语言》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白…

浅谈智能微电网供电系统的谐波治理

摘要&#xff1a;智能微电网供电系统的特性容易引发谐波&#xff0c;而谐波导致电力损耗加大&#xff0c;降低供电质量。本文从谐波的产 生原因和危害做出详细阐述&#xff0c;并结合智能微电网提出了治 理谐波的方法和措施。 关键词&#xff1a;智能微电网&#xff1b;谐波危害…

手术麻醉信息管理系统源码:全面监护,支持多设备采集

手术、麻醉是医院非常重要的一个组成部分&#xff0c;外科医生为病人进行手术的好与坏直接会危及到病人的生命&#xff0c;所以病人在手术麻醉过程中每一个环节都是非常重要的。随着现在高科技的发展&#xff0c;大量的医疗监视辅助仪器设备在手术过程中也得到广泛的应用&#…