数组排序——从荷兰国旗问题到快速排序

news2024/11/17 22:55:47

  本文首先将会介绍荷兰国旗问题,再讲述如何从该问题过渡到快速排序。

荷兰国旗问题

  荷兰国旗问题(Dutch National Flag Problem)是由荷兰计算机科学家Edsger Dijkstra所提出,该问题的描述如下:

给定n个红、白、蓝三种颜色的小球,无序地排列在一起。对这些小球进行排序,使得所有相同颜色的球在一起,且颜色顺序依次为红、白、蓝。

因荷兰国旗的颜色从上到下分别为红、白、蓝,故该问题被称为荷兰国旗问题
  事实上,在Leetcode中,该问题又被描述为:

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。要求使用的空间复杂度为常数空间。

因此,荷兰国旗问题又被称为颜色分类问题
  针对该问题,其解决的算法采用双指针法。我们采用两个指针lowhigh,分别指向0和2,再使用变量mid对数量进行遍历。具体的步骤如下:

  • 若mid遍历到的位置为0,则和low处的元素交换,同时向右移动low和mid。
  • 若mid遍历到的位置为1,则不需要处理,只需向右移动mid。
  • 若mid遍历到的位置为2,则和high处的元素交换,交换后只把high向左移动,mid仍然指向原位置。

整个算法的示意图如下:
荷兰国旗问题的算法示意图
上述算法的Python代码如下:

def sort_colors(nums):
    low, high, mid = 0, len(nums)-1, 0
    while mid <= high:
        if nums[mid] == 0:
            nums[low], nums[mid] = nums[mid], nums[low]
            low += 1
            mid += 1
        elif nums[mid] == 2:
            nums[high], nums[mid] = nums[mid], nums[high]
            high -= 1
        else:
            mid += 1
    return nums


if __name__ == '__main__':
    numbers = [1, 0, 1, 0, 2, 0, 2, 1]
    result = sort_colors(numbers)
    print(result)

输出结果如下:

[0, 0, 0, 1, 1, 1, 2, 2

快速排序

  对于上述的荷兰国旗问题,我们可以将思路拓宽,用它来实现快速排序。
  对于数组array,我们取其切片,即从位置low到high的数组片段(包括位置low和high),我们使用类似于荷兰国旗问题的思路,先选择一个数字作为枢纽(pivot),再找到合适的位置,使其作为小于pivot的数字排列和等于pivot的数字排列的分割点(类似于荷兰国旗问题中的数字0和1的分割点位置low)。
  接着,我们再循环调用上述算法,实现整个数组(从位置0到长度-1的数组切片)的排序。
  上述算法的Python实现代码如下:

def partition(array, low, high):
    pivot = array[low]
    a, b, c = low, high, low
    while c <= b:
        if array[c] < pivot:
            array[a], array[c] = array[c], array[a]
            a += 1
            c += 1
        elif array[c] > pivot:
            array[b], array[c] = array[c], array[b]
            b -= 1
        else:
            c += 1
    return a


def quick_sort(array, low, high):
    if low < high:
        pi = partition(array, low, high)
        # Recursive call on the left of pivot
        quick_sort(array, low, pi - 1)
        # Recursive call on the right of pivot
        quick_sort(array, pi + 1, high)
    return array


if __name__ == '__main__':
    n = 13
    my_list = list(range(n))
    from random import shuffle
    shuffle(my_list)
    print('排序前:', my_list)
    result = quick_sort(my_list, 0, len(my_list)-1)
    print('排序后:', result)

输出结果如下:

排序前: [12, 8, 7, 3, 1, 0, 4, 2, 9, 6, 11, 10, 5]
排序后: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

注意,该算法的时间复杂度为O(nlogn),空间复杂度为O(1).
  另外,还有其它的快速排序的实现代码,如下:

def quick_sort(array):
    n = len(array)
    if n <= 1:
        return array
    pivot = array[n//2]
    left = [x for x in array if x < pivot]
    middle = [x for x in array if x == pivot]
    right = [x for x in array if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

但显然,该实现代码在空间复杂度上不如上一种。

总结

  近来ChatGPT大火,我们也尝试着用ChatGPT来实现快速排序,如下:

chatgpt实现快速排序
  本文介绍了荷兰国旗问题,并将其扩展至排序排序,并介绍了两种快速排序的算法,最后再用ChatGPT来实现快速排序。

参考文献

  1. 荷兰国旗问题: https://juejin.cn/post/6890141987988340749
  2. 颜色分类: https://leetcode.cn/problems/sort-colors/description/
  3. QuickSort:https://www.geeksforgeeks.org/quick-sort/

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

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

相关文章

JNDI学习笔记

最近在研究JNDI注入漏洞&#xff0c;就先浅浅的学习以下JNDI相关知识。 JNDI对各种目录服务的实现进行抽象和统一化。 在 Java 应用中除了以常规方式使用名称服务(比如使用 DNS 解析域名)&#xff0c;另一个常见的用法是使用目录服务作为对象存储的系统&#xff0c;即用目录服务…

SpringBoot --- 基础篇

一、快速上手SpringBoot 1.1、概述 SpringBoot开发团队认为原始的Spring程序初始搭建的时候可能有些繁琐&#xff0c;这个过程是可以简化的&#xff0c;那原始的Spring程序初始搭建过程都包含哪些东西了呢&#xff1f;为什么觉得繁琐呢&#xff1f;最基本的Spring程序至少有一…

大数据:VMware | Ubuntu | Hadoop | Spark | VMwaretools | Python 安装配置总结

一.环境概述 Linux发行版&#xff1a;Ubuntu虚拟机应用&#xff1a;VMware Workstation ProHadoop版本&#xff1a;3.1.3|伪分布式集群JDK版本&#xff1a;JDK1.8.0_162Spark版本:2.4.0Scala版本:2.12.8Python版本:3.6.8 | 3.7.16 二.Ubuntu 2.1 光盘文件 首先进入链接Down…

因为AI,我被裁了;MJ设计海报全流程;独立开发者每周收入2.3K美元;MJ常用参数超详细介绍 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 受 AI 影响&#xff0c;这 8 家公司开始裁员…… 为了搞清楚 AI 最近在影响哪些行业、哪些职业&#xff0c;作者花了三天事件找到了八…

基于SSM的网络在线考试系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 前言…

《Java并发编程实战》课程笔记(二)

可见性、原子性和有序性问题&#xff1a;并发编程 Bug 的源头 源头之一&#xff1a;缓存导致的可见性问题 在单核时代&#xff0c;所有的线程都是在一颗 CPU 上执行&#xff0c;CPU 缓存与内存的数据一致性容易解决。 因为所有线程都是操作同一个 CPU 的缓存&#xff0c;一个…

《面试1v1》ThreadLocal

我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a; 你好&#xff0c;请问你对 ThreadLocal 有了解吗&#xff1f; 候选人&#xff1a; 您好&#xff0c;我知道 ThreadLocal 是一个 Java 中的类&a…

【坐标变换】坐标系坐标变换简单推导--未完待续

如图所示&#xff0c;假设已知坐标系 ( X , Y ) (X,Y) (X,Y)&#xff0c;旋转后的坐标系为 ( X ′ , Y ′ ) (X,Y) (X′,Y′)&#xff0c;旋转角度为 θ \theta θ&#xff0c;假设点p在 ( X , Y ) (X,Y) (X,Y)坐标系下为 ( x , y ) (x,y) (x,y)&#xff0c;坐标在旋转后的坐标…

速来!谷歌师兄的LeetCode刷题笔记开源了!

有小伙伴私聊我说刚开始刷LeetCode的时候&#xff0c;感到很吃力&#xff0c;刷题效率很低。我以前刷题的时候也遇到这个问题&#xff0c;直到后来看到这个谷歌师兄总结的刷题笔记&#xff0c;发现LeetCode刷题都是套路呀&#xff0c;掌握这些套路之后&#xff0c;就变得非常简…

kubernetes高可用+harbor高可用

kubernetes高可用harbor高可用 基于kubeadm安装kubernetes高可用集群全部主机环境初始化双主节点部署keepalive双主节点初始化kubeadm在k8smaster1节点上初始化k8s在k8smaster2节点上做扩容操作 harbor高可用集群初始化harbor1节点安装环境在另一台节点上配置使用私有harbor仓库…

初学QT:使用QtDesigner绘制一个简单的界面(Day01)

关于Qt 打算在这里记录我学习qt过程中遇见的问题的收获 今天是学习qt的第一天&#xff0c;首先找了一个界面打算照着这个界面写一个一样的 因为是第一天&#xff0c;所以我用的是qt designer写的 其中遇到的问题&#xff1a; 设置背景图片 首先不能直接添加图片到背景图片中…

如何在华为OD机试中获得满分?Java实现【分界线】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

在 Alma Linux 9 上安装 Node.js 的 3 种不同方法

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时&#xff0c;用于构建快速、可扩展的网络应用程序。在 Alma Linux 9 上安装 Node.js 可以为开发者提供强大的工具和库来开发服务器端应用程序。 本文将介绍三种不同的方法来安装 Node.js 在 Alma Linux 9 上。 1. 方法一…

LLMs的自动化工具系统(HuggingGPT、AutoGPT、WebGPT、WebCPM)

在前面两篇博文中已经粗略介绍了增强语言模型和Tool Learning&#xff0c;本篇文章看四篇代表性的自动化框架&#xff0c;HuggingGPT、AutoGPT、WebGPT、WebCPM。 Augmented Language Models&#xff08;增强语言模型&#xff09;Toolformer and Tool Learning&#xff08;LLM…

chatgpt赋能python:了解PythonSpace:Python编程中的重要概念

了解Python Space&#xff1a;Python编程中的重要概念 Python Space是Python编程的一个关键概念&#xff0c;可以帮助你更好地理解Python中的命名空间和作用域。在这篇文章中&#xff0c;我们将深入探讨Python Space&#xff0c;介绍命名空间的概念&#xff0c;讨论命名空间和…

支付系统设计四:支付核心设计03-快捷发送短信(失败转代扣)

文章目录 前言一、背景1. 应用架构2. 分层支撑机制 二、银行卡快捷支付1. 用户操作流程2. 系统执行流程--正常2.1 发送短信2.2 短信确认 3. 系统执行流程--异常3.1 异常环节3.1.1 路由失败3.1.2 调用支付渠道失败 3.2 异常处理3.2.1 路由失败3.2.2 调用支付渠道失败 4. 流程解析…

指导实验心得5篇实用技巧

指导实验心得1 我觉得化工原理实验是一门验证性课程&#xff0c;它把我们在化工原理学到的各种单元操作化为实实在在的东西&#xff0c;而让我们把学到的知识认识到它的实在性。流体输送——离心泵、过滤——板框压滤机、对流传热——套管式换热器、吸收蒸馏——填料塔板式塔、…

AF594 NHS,Alexa Fluor594 NHS Ester,AF 594 NHS 活化酯,用于成像和流式细胞术中的稳定信号生成

【产品描述】 陕西新研博美生物科技有限公司供应的​Alexa Fluor594是一种鲜红色染料。Alexa Fluor用于成像和流式细胞术中的稳定信号生成 594染料是水溶性的&#xff0c;并且从pH 4到pH 10对pH不敏感。Alexa Fluor 594染料与多种抗体、肽、蛋白质、示踪剂和扩增底物偶联&#…

java内存问题

各种OOM的情况 1. 堆溢出-java.lang.OutOfMemoryError: Java heap space。 2. 栈溢出-java.lang.OutOfMemorryError。 3. 栈溢出-java.lang.StackOverFlowError。 4. 元信息溢出-java.lang.OutOfMemoryError: Metaspace。 5. 直接内存溢出-java.lang.OutOfMemoryError: Direct …

软件开发工程师个人简历模板3篇

软件开发工程师个人简历模板篇1 姓 名&#xff1a; 张先生 性 别&#xff1a; 男 婚姻状况&#xff1a; 未婚 民 族&#xff1a; 汉族 户 籍&#xff1a; 广东-珠海 年 龄&#xff1a; 28 现所在地&#xff1a; 广东-珠海 身 高&#xff1a; 168cm 希望地区&#xff1a; …