十大经典排序算法-快速排序算法详解

十大经典排序算法-快速排序算法详解一、什么是快速排序1.概念快速排序(QuickSort)是从冒泡排序算法演变而来的,实际上是在冒泡排序基础上的递归分治法。快速排序在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边,比它小的元素移动到数列的另一边,从而把数列拆解成了两个部分2.算法原理这是一个无序数列:4、5、8、1、7、2、6、3,我们要将它按从小到大排序。按照快速排序的思想,我们先选择一个基准元素,进行排序我们选取4为我们的基准元素,并设置基准元素的位置为index,设置两个指针left和right,分别指向最左

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

十大经典排序算法

一、什么是快速排序

1.概念

快速排序(Quick Sort)是从冒泡排序算法演变而来的,实际上是在冒泡排序基础上的递归分治法。快速排序在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边,比它小的元素移动到数列的另一边,从而把数列拆解成了两个部分

2.算法原理

这是一个无序数列:4、5、8、1、7、2、6、3,我们要将它按从小到大排序。按照快速排序的思想,我们先选择一个基准元素,进行排序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BeR19ua8-1592286987672)(./快速1.png)]
我们选取4为我们的基准元素,并设置基准元素的位置为index,设置两个指针left和right,分别指向最左和最右两个元素
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6EFkeo4Z-1592286987676)(./快速2.png)]
接着,从right指针开始,把指针所指向的元素和基准元素做比较,如果比基准元素大,则right指针向左移动,如果比基准元素小,则把right所指向的元素填入index中

3和4比较,3比4小,将3填入index中,原来3的位置成为了新的index,同时left右移一位
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2ahJscJM-1592286987677)(./快速3.png)]
然后,我们切换left指针进行比较,如果left指向的元素小于基准元素,则left指针向右移动,如果元素大于基准元素,则把left指向的元素填入index中

5和4比较,5比4大,将5填入index中,原来5的位置成为了新的index,同时right左移一位
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-28sZ32EQ-1592286987678)(./快速4.png)]
接下来,我们再切换到right指针进行比较,6和4比较,6比4大,right指针左移一位
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BmFtPyoS-1592286987680)(./快速5.png)]
2和4比较,2比4小,将2填入index中,原来2的位置成为新的index,left右移一位
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-At3QbmBx-1592286987682)(./快速6.png)]
随着left右移,right左移,最终left和right重合
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WfcU8kdr-1592286987684)(./快速7.png)]
此时,我们将基准元素填入index中,这时,基准元素左边的都比基准元素小,右边的都比基准元素大,这一轮交换结束
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VjOiHUyg-1592286987685)(./快速8.png)]
第一轮,基准元素4将序列分成了两部分,左边小于4,右边大于4,第二轮则是对拆分后的两部分进行比较

此时,我们有两个序列需要比较,分别是3、2、1和7、8、6、5,重新选择左边序列的基准元素为3,右边序列的基准元素为7
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xTPfcLIT-1592286987686)(./快速9.png)]
第二轮排序结束后,结果如下所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YvVyuVCL-1592286987686)(./快速10.png)]
此时,3、4、7为前两轮的基准元素,是有序的,7的右边只有8一个元素也是有序的,因此,第三轮,我们只需要对1、2和5、6这两个序列进行排序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gDg3vGlK-1592286987687)(./快速11.png)]
第三轮排序结果如下所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BT70Q2eJ-1592286987690)(./快速12.png)]
至此所有的元素都是有序的

3.算法实现

function sort(arr, startIndex, endIndex) {
    // 递归结束条件:startIndex大于等于endIndex的时候
    if (startIndex >= endIndex) {
        return;
    }
    // 得到基准元素的位置
    let pivotIndex = partition(arr, startIndex, endIndex);
    sort(arr, startIndex, pivotIndex - 1);
    sort(arr, pivotIndex + 1, endIndex);
}

function partition(arr, startIndex, endIndex) {
    // 选择第一个位置的元素作为基准元素
    let pivot = arr[startIndex];
    let left = startIndex;
    let right = endIndex;
    let index = startIndex;

    // 外循环在左右指针重合或者交错的时候结束
    while (right > left) {
        // right指针从右向左进行比较
        while (right > left) {
            if (arr[right] < pivot) {
                arr[left] = arr[right];
                index = right;
                left++;
                break;
            }
            right--;
        }
        // left指针从左向右进行比较
        while (right > left) {
            if (arr[left] > pivot) {
                arr[right] = arr[left];
                index = left;
                right--;
                break;
            }
            left++;
        }
    }
    arr[index] = pivot;
    return index;
}

let arr = [4, 5, 8, 1, 7, 2, 6, 3];
sort(arr, 0, arr.length - 1);
console.log(arr);

三、快速排序算法特点

1.时间复杂度

快速排序算法在分治法的思想下,原数列在每一轮被拆分成两部分,每一部分在下一轮又分别被拆分成两部分,直到不可再分为止,平均情况下需要logn轮,因此快速排序算法的平均时间复杂度是O(nlogn)

在极端情况下,快速排序算法每一轮只确定基准元素的位置,时间复杂度为O(N^2)

2.空间复杂度

快速排序算法排序过程中只是使用数组原本的空间进行排序,因此空间复杂度为O(1)

3.稳定性

快速排序算法在排序过程中,可能使相同元素的前后顺序发生改变,所以快速排序是一种不稳定排序算法

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/159455.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Tarjan_com.pakdata.QuranMajeed

    Tarjan_com.pakdata.QuranMajeedTarjanTarjan是一种求有向图强联通分量的算法,是用dfs实现以及时间戳标记访问最短时间的.Tarjan算法中每个点都需要扩展边,为了存储方便,推荐使用邻接表.Tarjan算法的优势在于其灵活性,基础代码可以直接适用于多数情况.常见于dfs序.

    2025年7月15日
    3
  • 在 Ubuntu 12.04 上通过安装源安装 Open vSwitch (OVS)

    在 Ubuntu 12.04 上通过安装源安装 Open vSwitch (OVS)

    2021年12月9日
    77
  • Java——从键盘输入数组

    Java——从键盘输入数组补充知识JavaScanner类java.util.Scanner是Java5的新特征,我们可以通过Scanner类来获取用户的输入。toString()方法用于返回以一个字符串表示的Number对象值。目录补充知识一、从键盘获取不限制长度的数组输出结果二、从键盘获取限制长度的数组输出结果三、参考一、从键盘获取不限制长度的数组importjava.util.Scanner;publicclassInputArrayNoLimitLength{ publicst

    2022年6月26日
    31
  • 复变函数—–区域「建议收藏」

    复变函数—–区域「建议收藏」邻域、去心邻域平面上以Z0为中心,δ(任意的正数)为半径的圆:|Z-Z0|<δ内部的点的集合称为Z0的邻域,而称由不等式0<|Z-Z0|<δ所确定的点集为Z0的去心邻域。内点、开集设G为一平面点集,Z0为G中任意一点,如果存在Z0的一个邻域,该邻域内的所有点都属于G,那么称Z0为G的内点。如果G内的每个点都是它的内点,那么称G为开集。区域平面点集D称为一个区域,如果满足下列两个条件:1.D是一个开集;2.D是连通的,就是说D中任何两点都可以用完全属于D的一条折线连

    2022年7月15日
    26
  • linux 内核 – ioctl 函数详解

    linux 内核 – ioctl 函数详解1.概念ioctl是设备驱动程序中设备控制接口函数,一个字符设备驱动通常会实现设备打开、关闭、读、写等功能,在一些需要细分的情境下,如果需要扩展新的功能,通常以增设ioctl()命令的方式实现。在文件I/O中,ioctl扮演着重要角色,本文将以驱动开发为侧重点,从用户空间到内核空间纵向分析ioctl函数。2.用户空间ioctl#include&…

    2022年10月18日
    2
  • 【ZigBee协议栈简介】

    【ZigBee协议栈简介】1、Zigbee协议栈简介  协议是一系列的通信标准,通信双方需要按照这一标准进行正常的数据发射和接收。协议栈是协议的具体实现形式,通俗讲协议栈就是协议和用户之间的一个接口,开发人员通过使用协议栈来使用这个协议,进而实现无线数据收发。  如图1所示:Zigbee协议分为两部分,IEEE802.15.4定义了PHY(物理层)和MAC(介质访问层)技术规范;Zigbee联盟定义了NWK(网络…

    2022年5月28日
    54

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号