【算法实践】| 手把手带你实现快速排序算法

简介: 之前在《利用 Python 浅尝算法分析》这篇文章中写过算法分析,接着写了关于经典的冒泡排序算法《利用 Python 手把手带上实现冒泡排序》,算法虽然枯燥,但是当你深入了解就会感受到其中的趣味。在算法的学习中不但可以学会如何思考问题,提高自己的逻辑能力,还能在这些算法中积累解决实际生活问题的方法。算法是无穷无尽的,在编程中他可以是任意一段代码。我们平时在实际开发中涉及到的算法,很多都是衍生于经典算法,或者是多种经典算法的结合,所以学习算法,经典算法是我们绕不过的一道坎、只有跨过去才能这道坎另一边的好风景,方能走得更远,学习经典算法的好处就不多说了。。。直接进入今天的主题--快速排序的实现快

前言


我们知道,程序是用来解决问题的,是由多个步骤或过程组成的,这些步骤和过程就是解决问题的算法。


网络异常,图片无法展示
|
网络异常,图片无法展示
|


之前在《利用 Python 浅尝算法分析》这篇文章中写过算法分析,接着写了关于经典的冒泡排序算法《利用 Python 手把手带上实现冒泡排序》,算法虽然枯燥,但是当你深入了解就会感受到其中的趣味。在算法的学习中不但可以学会如何思考问题,提高自己的逻辑能力,还能在这些算法中积累解决实际生活问题的方法。算法是无穷无尽的,在编程中他可以是任意一段代码。我们平时在实际开发中涉及到的算法,很多都是衍生于经典算法,或者是多种经典算法的结合,所以学习算法,经典算法是我们绕不过的一道坎、只有跨过去才能这道坎另一边的好风景,方能走得更远,学习经典算法的好处就不多说了。。。直接进入今天的主题--快速排序的实现


快速排序,跟冒泡排序算法一样,顾名思义就是一种排序算法,快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,他将原本的问题分成两个子问题,各个击破,通常称其为分治法(Divide-and-ConquerMethod)。

快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,再加上快速排序思想—-分治法也确实实用,这也使得在我们的面试或者工作中经常出现的它的身影,这个算法有些复杂,时间复杂度最好的情况是O(nlogn),最差的情况是O(n^2),而且比较不稳定,占用空间O(logn)


该方法的基本思想是:


1.先从数列中选择一个数作为基准数。

2.分区过程:通过排序,将数据分割成独立的两部分.将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

3.按此方法,再对左右区间重复第二步,直到各区间只有一个数

整个排序过程可以递归进行,以此达到数据排序的目的

虽然快速排序称为分治法,但分治法无法很好的概括快速排序的全部步骤。所以快速排序又总结为:挖坑填数+分治法,下面我们使用图示展示算法的基本过程


算法过程演示


以序列[2,7,6,5,4,3]为例进行排序:

随机选择一个数作为基准数.这里选择5作为基准数.比基准数大的往右移,比基准数小的往左移,直到把5的左边全部是比它小的数,右边全部是比它大的数,第一次完成一个整体排序后,接着对基准数的前后两个半区进行和前面一样的操作,直到整体的排序完成


网络异常,图片无法展示
|


实现步骤


快速排序步骤:

  1. 定义一个需要排序的列表
  2. 创建递归递归调用的快速排序函数
  3. 判断low是否小于high,若low>high,则直接返回原列表
  4. 设置基准数pivot
  5. 如果列表前半区的数比基准数小或相等,则向后移动一位,直到有比基准数大的数出现,放入后半区.如果列表后半区的数比基准数大或相等.则向前移动一位,直到有比基准数小的数出现,放入前半区内.
  6. 递归前后半区,然后返回列表
  7. 调用函数输出列表


流程如下:

网络异常,图片无法展示
|


代码实现


定义快速排序函数QuickSort(),low为列表最左边位置的编号,high为列表最右边的位置编号,如果low>high,直接返回原列表并将列表中第一个数字设置为基准数

defQuickSort(ListData,low,high):
iflow<high:
i,j=low,high#设置基准数pivot=ListData[i]
whilei<j:
#如果列表后边的数,比基准数大或相等,则前移一位直到有比基准数小的数出现while (i<j) and (ListData[j] >=pivot):
j=j-1#如找到,则把第j个元素赋值给第个元素i,此时表中i,j个元素相等ListData[i] =ListData[j]
#以同样的方式比较前半的子序列while (i<j) and (ListData[i] <=pivot):
i=i+1ListData[j] =ListData[i]
#做完第一轮比较之后,列表被分成了两个子序列,并且i=j,需要将这个数设置回选择的基准数ListData[i] =pivot#递归基准数的前后两个子序列QuickSort(ListData, low, i-1)
QuickSort(ListData, j+1, high)
returnListData

调用QuickSort()验证排序算法:

ListData= [2,7,6,5,4,3]
print("原列表: ",ListData)
QuickSort(ListData,0,len(ListData)-1)
print("已排序列表: ",ListData)


执行结果如下:

网络异常,图片无法展示
|


总结


快速排序是一种分治法.它将原本的问题分成两个子问题,然后再分别解决这两个子问题.子问题就是子序列完成排序,然后再把它们合并成一个整体.那么对原始序列的排序也就完成了.解决子问题的时候会再次使用快速排序,甚至在这个快速排序里仍要使用快速排序.就像俄罗斯套娃,直到子问题里只剩一个数字,排序才算法完成,这种做法就是传说中的递归

分割子序列时需要选择基准数,如果每次选择的基准数都能使得两个子序列的长度为原来的一半,那么快速排序的运行时间为:O(nlogn),将序列对半分割log2n次之后子序列里便只剩下一个数据,这时子序列的排序也就完成了.也就是说如果把根据基准数分割序列的整个过程一行行地展现.总共有log2n行,每轮(每行)每个数都需要和基准数比较大小,因此每行所需要的运行时间为O(n),所以快速排序的整体的时间复杂度为O(nlogn)


如果运气不好的话,每次都选择到最小值作为基准数,那每次都需要把其他数据移到基准数右边,然后递归执行n轮,运行时间也就成了O(n*2);这就相当于每次都选出最小值并把它移到了最左边,这个操作就和选择排序一样了.还有,如果数据中的每个数字被选为基准数的概率都相等,需要的平均运行时间为O(nlogn)

目录
相关文章
|
6天前
|
搜索推荐 算法 Java
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
该博客文章通过UML类图和Java源码示例,展示了如何使用适配器模式将QuickSort类和BinarySearch类的排序和查找功能适配到DataOperation接口中,实现算法的解耦和复用。
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
|
2天前
|
机器学习/深度学习 人工智能 算法
【人工智能】传统语音识别算法概述,应用场景,项目实践及案例分析,附带代码示例
传统语音识别算法是将语音信号转化为文本形式的技术,它主要基于模式识别理论和数学统计学方法。以下是传统语音识别算法的基本概述
7 2
|
9天前
|
机器学习/深度学习 数据采集 人工智能
理解并应用机器学习算法:从技术基础到实践应用
【8月更文挑战第10天】机器学习算法的应用已经深入到我们生活的方方面面,理解和掌握机器学习算法对于数据科学家、工程师乃至普通从业者来说都至关重要。通过本文的介绍,希望大家能够对机器学习有一个基本的认识,并学会如何将其应用于实际问题中。当然,机器学习是一个不断发展和演变的领域,只有不断学习和实践,才能跟上时代的步伐。
|
19天前
|
机器学习/深度学习 数据采集 人工智能
AI技术实践:利用机器学习算法预测房价
人工智能(Artificial Intelligence, AI)已经深刻地影响了我们的生活,从智能助手到自动驾驶,AI的应用无处不在。然而,AI不仅仅是一个理论概念,它的实际应用和技术实现同样重要。本文将通过详细的技术实践,带领读者从理论走向实践,详细介绍AI项目的实现过程,包括数据准备、模型选择、训练和优化等环节。
118 3
|
19天前
|
缓存 负载均衡 算法
(四)网络编程之请求分发篇:负载均衡静态调度算法、平滑轮询加权、一致性哈希、最小活跃数算法实践!
先如今所有的技术栈中,只要一谈关于高可用、高并发处理相关的实现,必然会牵扯到集群这个话题,也就是部署多台服务器共同对外提供服务,从而做到提升系统吞吐量,优化系统的整体性能以及稳定性等目的。
|
22天前
|
机器学习/深度学习 数据采集 算法
推荐引擎离线算法与在线算法的探索与实践
推荐引擎是现代互联网产品中至关重要的组成部分。离线算法和在线算法分别负责处理大量数据的预处理和模型训练,以及快速响应用户的实时请求。通过合理的架构设计和算法选择,可以构建出高效且个性化的推荐系统,从而提升用户体验,增加用户满意度和留存率。未来,随着技术的发展,推荐引擎将更加智能化和个性化,为用户提供更加精准的服务。
|
1月前
|
监控 算法 自动驾驶
目标检测算法:从理论到实践的深度探索
【7月更文第18天】目标检测,作为计算机视觉领域的核心任务之一,旨在识别图像或视频中特定对象的位置及其类别。这一技术在自动驾驶、视频监控、医疗影像分析等多个领域发挥着至关重要的作用。本文将深入浅出地介绍目标检测的基本概念、主流算法,并通过一个实际的代码示例,带您领略YOLOv5这一高效目标检测模型的魅力。
155 11
|
4天前
|
算法 搜索推荐
算法设计 (分治法应用实验报告)基于分治法的合并排序、快速排序、最近对问题
这篇文章是关于分治法应用的实验报告,详细介绍了如何利用分治法实现合并排序和快速排序算法,并探讨了使用分治法解决二维平面上的最近对问题的方法,包括伪代码、源代码实现及时间效率分析,并附有运行结果和小结。
|
28天前
|
机器学习/深度学习 数据采集 人工智能
机器学习算法入门与实践
【7月更文挑战第22天】机器学习算法入门与实践是一个既充满挑战又极具吸引力的过程。通过掌握基础知识、理解常见算法、注重数据预处理和模型选择、持续学习新技术和参与实践项目,你可以逐步提高自己的机器学习技能,并在实际应用中取得优异的成绩。记住,机器学习是一个不断迭代和改进的过程,保持好奇心和耐心,你将在这个领域走得更远。
|
28天前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【7月更文挑战第22天】在大数据领域,Python算法效率至关重要。本文深入解析时间与空间复杂度,用大O表示法衡量执行时间和存储需求。通过冒泡排序(O(n^2)时间,O(1)空间)与快速排序(平均O(n log n)时间,O(log n)空间)实例,展示Python代码实现与复杂度分析。策略包括算法适配、分治法应用及空间换取时间优化。掌握这些,可提升大数据处理能力,持续学习实践是关键。
33 1

热门文章

最新文章