【代码刷题】排序算法总结(python实现)

排序算法总结(Python实现)

  • 算法介绍
    • 算法分类
    • 相关概念
  • 1. 冒泡排序(Bubble Sort)
    • 1.1 思想
    • 1.2 python实现
    • 1.3 复杂度
    • 1.4 稳定性
  • 2. 快速排序(Quick Sort)
    • 2.1 思想(伪代码)
    • 2.2 python实现
      • 2.3 复杂度
      • 2.4 稳定性
  • 3.直接插入排序(Insert Sort)
    • 3.1 思想
    • 3.2 python实现
    • 3.3 复杂度
    • 3.4 稳定性
  • 4. 希尔排序(Shell Sort)
    • 4.1 思想
    • 4.2 python实现
    • 4.3 复杂度
    • 4.4 稳定性
  • 5. 直接选择排序
    • 5.1 思想
    • 5.2 python实现
    • 5.3 复杂度
    • 5.4 稳定性
  • 6. 堆排序(Heap Sort)
    • 6.1 思想
    • 6.2 python实现
  • 7. 归并排序
    • 7.1 思想
    • 7.2 python实现
  • 8. 基数排序
    • 8.1 思想
    • 8.2 python实现

算法介绍

在这里插入图片描述

算法分类

内部排序:数据在内存里排序
外部排序:数据处理在硬盘上的排序(如数据太多没法都读到内存)
  • 交换排序:比较两个记录键值的大小,如果这两个记录键值的大小出现逆序,则交换这两个记录,这样将键值较小的记录向序列前部移动,键值较大的记录向序列后部移动。
  • 插入排序:依次将每个记录插入到一个已排好序的有序表中去
  • 选择排序:依次在未排序序列中找到最小元素,存放到排好序列的起始位置。

相关概念

1. 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
2. 不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
3. 时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
4. 空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。

1. 冒泡排序(Bubble Sort)

1.1 思想

1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。 
3. 针对所有的元素重复以上的步骤,除了最后一个。 
4. 重复步骤1~3,直至排序完成。
begin BubbleSort(list)for all elements of listif list[i] > list[i+1]swap(list[i], list[i+1])end if...
  • 冒泡排序只对n个数据操作n-1轮,每轮找出最大(小)值
  • 通过比较与交换相邻两个数,每轮将未排序序列中最大(小)值“冒泡”至列首(尾)。

1.2 python实现

def BubbleSort(lst):n = len(lst)if n < = 1:return lstfor i in range(n - 1): # 循环次数,每一轮确定一个最值for j in range(n - i - 1): # 待比较与交换的数if lst[j] > lst[j+1]: # 比较两个相邻的数,如果后者<前者,交换lst[j], lst[j+1] = lst[j+1], lst[j] return lst
arr = list(map(int, input().split()))
arr = BubbleSort(arr)
for i in arr:print(i, end =' ')

1.3 复杂度

  • 时间复杂度:O(n2),每轮操作O(n),共O(n)轮。
  • 空间复杂度:O(1),额外空间开销出在交换数据时的一个过渡空间。

1.4 稳定性

  • 稳定

2. 快速排序(Quick Sort)

2.1 思想(伪代码)

1. 从数列中挑出一个元素,称为 “基准”(pivot);
2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
  • 快速排序基于选择划分,是简单选择排序的优化。
  • 每次划分将数据选到基准值两边,循环对两边的数据进行划分,类似于二分法。
  • 算法的整体性能取决于划分的平均程度,即基准值的选择,此处衍生出快速排序的许多优化方案,甚至可以划分为多块。
#分区操作#
function partitionFunc(left, right, pivot)leftPointer = leftrightPointer = right - 1while True dowhile A[++leftPointer] < pivot do//do-nothing            end whilewhile rightPointer > 0 && A[--rightPointer] > pivot do//do-nothing         end whileif leftPointer >= rightPointerbreakelse                swap leftPointer,rightPointerend ifend while swap leftPointer,rightreturn leftPointerend function
#递归快排#
procedure quickSort(left, right)if right-left <= 0returnelse     pivot = A[right]partition = partitionFunc(left, right, pivot)quickSort(left,partition-1)quickSort(partition+1,right)    end if		end procedure

2.2 python实现

参考link

def QuickSort(lst):def partition(arr,left,right):pivot = arr[left] # 划分参考数索引,默认为第一个数为基准数,可优化while left < right:# 如果列表后边的数,比基准数大或相等,则前移一位直到有比基准数小的数出现while left < right and arr[right] >= pivot:right-=1# 此时right指向一个比基准数小的数,将right指向的数放去left的位置上,此时right指向的位置空着,接下来移动left找到符合条件的数放在此处arr[left] = arr[right]# 如果列表前边的数,比基准数小或相等,则后移一位直到有比基准数小的数出现while left < right and arr[left] <= pivot:left+=1# 此时left指向一个比基准数大的数,将left指向的数放去right的位置上,此时left指向的位置空着,接下来进入下一次循环,将right找到符合条件的数放在此处arr[right] = arr[left]# 推出循环后,left和right重合,此时所致位置即为基准元素正确的位置,此时,左边的元素都比pivot小,右边的都比pivot大arr[left] = pivot # 将基准元素放到该位置return left # 返回基准元素位置def quicksort(arr, left, right):if left >= right:  # 递归退出条件return  mid = partition(arr,left,right) # 分区,得到基准元素位置# 递归调用快排quicksort(arr,left,mid-1) # 对基准元素左边的子序列快排quicksort(arr,mid+1,right) # 对基准元素右边的子序列快排# 主函数n=len(lst)if n<=1:return lstquicksort(lst,0,n-1) # 调用快排return lstif __name__ == "__main__":arr = list(map(int, input().split()))arr = QuickSort(arr)for i in arr:print(i, end =' ')

2.3 复杂度

  • 时间复杂度:O(nlogn),划分次数O(logn),每次划分遍历比较O(n)
  • 空间复杂度:O(logn),额外空间开销出在暂存基准值,O(logn)划分需要O(logn)个。

2.4 稳定性

  • 不稳定

3.直接插入排序(Insert Sort)

3.1 思想

基本思想:依次将每个记录插入到一个已排好序的有序表中去,从而得到一个新的、记录数增加1的有序表
  • 步骤:
  1. 从第一个元素开始,该元素可以被认为已经被排好序;
  2. 取出下一个元素,在已经排好序的元素序列中从后向前扫描;
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  5. 将新元素插入到该位置后;
  6. 重复步骤2~5,直至最后一个元素被插入到合适的位置。

3.2 python实现

def InsertSort(lst):n = len(lst)if n <=1:return lstfor i in range(1,n):j = inum = lst[i] # 每次循环的等待插入的数while j > 0 and num < lst[j-1]: # 比较、后移,给待插入数num腾位lst[j] = lst[j-1]j = j-1lst[j] = num # 把待插入数num插到空位return lstif __name__ == "__main__":arr = list(map(int, input().split()))arr = InsertSort(arr)for i in arr:print(i, end =' ')

3.3 复杂度

  • 时间复杂度:O(n2),每轮操作O(n)次,共O(n)轮。
  • 空间复杂度:O(1),额外空间开销出在数据移位时那一个过渡空间

3.4 稳定性

  • 稳定

4. 希尔排序(Shell Sort)

4.1 思想

基本思想:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序
  • 步骤
  1. 选择一个增量序列t1,t2,…,tk,其中ti>tk,tk=1
  2. 按增量序列个数k,对序列进行k趟排序
  3. 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
    在这里插入图片描述
    图源:link
  • 希尔排序是插入排序的高效实现,减少直接插入排序移动次数。由于简单插入排序每次插入都要移动大量数据,前后插入时的许多移动都是重复操作,若一步到位移动效率会高很多。
  • 若序列基本有序,简单插入排序只需要比较,不必做很多移动操作,效率很高。
  • 希尔排序将序列按固定间隔划分为多个子序列,在子序列中简单插入排序,先做远距离移动使序列基本有序;逐渐缩小间隔重复操作,最后间隔为1时即简单插入排序。

4.2 python实现

def ShellSort(lst):def shellinsert(arr, d):n = len(arr)for i in range(d,n):j = i - dnum = arr[i]  # 记录要插入的数while (j >= 0 and arr[j] > num):  # 从后向前,找到比其小的数的位置arr[j + d] = arr[j]  # 向后挪动j -= dif j != i - d:arr[j + d] = numn = len(lst)if n <= 1:return lstd = n // 2while d >= 1:shellinsert(lst, d)d = d // 2return lstif __name__ == "__main__":arr = list(map(int, input().split()))arr = ShellSort(arr)for i in arr:print(i, end =' ')

4.3 复杂度

  • 时间复杂度:O(nlogn),对序列划分O(n)次,每次简单插入排序O(logn)
  • 空间复杂度:O(1),额外空间开销出在插入过程数据移动需要的一个暂存

4.4 稳定性

  • 不稳定

5. 直接选择排序

5.1 思想

核心思想:简单选择排序同样对数据操作n-1轮,每轮找出一个最大(小)值。
  • 步骤
  1. 初始状态:无序区为R[1…n],有序区为空;
  2. 第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1…i-1]和R(i…n)。该趟排序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1…i]和R[i+1…n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;
  3. n-1趟结束,数组有序化了。

5.2 python实现

def SelectSort(lst):n = len(lst)if n<=1:return lstfor i in range(n-1):minIndex = ifor j in range(i+1,n): #比较一遍,记录索引不交换if lst[j]<lst[minIndex]:minIndex = jif minIndex!=i: #按索引交换lst[minIndex],lst[i] = lst[i], lst[minIndex]return lstif __name__ == "__main__":arr = list(map(int, input().split()))arr = SelectSort(arr)for i in arr:print(i, end =' ')

5.3 复杂度

  • 时间复杂度:O(2),比较O(n)轮,每轮操作O(n)次
  • 空间复杂度:O(1)

5.4 稳定性

  • 稳定

6. 堆排序(Heap Sort)

6.1 思想

核心思想:堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
  • 步骤
  1. 将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;
  2. 将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足R[1,2…n-1]<=R[n];
  3. 由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

6.2 python实现

7. 归并排序

7.1 思想

7.2 python实现

8. 基数排序

8.1 思想

8.2 python实现

未完待续…

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

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

相关文章

C语言遍历目录

C语言遍历目录&#xff0c;可以循环的遍历子目录#include <stdio.h>#include <string.h>#include <stdlib.h>#include <dirent.h>#include <sys/stat.h>#include <unistd.h>#include <sys/types.h>void listDir(char *path){struct …

学成在线--11.RabbitMQ快速入门

文章目录一.RabbitMQ简介二.相关知识1.AMQP2.JMS是什么 &#xff1f;三.RabbitMQ的工作原理四.Hello World1.创建Maven工程2.生产者3.消费者五.总结一.RabbitMQ简介 MQ全称为Message Queue&#xff0c;即消息队列&#xff0c; RabbitMQ是由erlang语言开发&#xff0c;基于AMQP…

数据库断言

SQL中&#xff0c;可以使用 CREATE ASSERTION语句&#xff0c;通过声明性断言来指定更具一般性的约束。 可以定义涉及多个表的或聚集操作的比较复杂的完整性约束。 断言创建以后&#xff0c;任何对断言中所涉及的关系的操作都会触发关系数据库管理系统对断言的检查&#xff0c;…

mysql帐号不允许从远程登陆

默认情况下&#xff0c;mysql帐号不允许从远程登陆&#xff0c;只能在localhost登录。本文提供了二种方法设置mysql可以通过远程主机进行连接。 一、改表法 在localhost登入mysql后&#xff0c;更改 “mysql” 数据库里的 “user” 表里的 “host” 项&#xff0c;将”localhos…

maven工程建立和SSM(springMVC+spring+mybatis)整合

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1.环境&#xff1a; maven 版本&#xff1a;3.5.1 ecelipse mars.2 JDK : jdk1.8.0_45 tomcat : apache-tomcat-8.0.0-RC1 2. 建…

Java——网络编程(实现基于命令行的多人聊天室)

2019独角兽企业重金招聘Python工程师标准>>> 目录&#xff1a; 1.ISO和TCP/IP分层模型 2.IP协议 3.TCP/UDP协议 4.基于TCP的网络编程 5.基于UDP的网络编程 6.基于TCP的多线程的聊天室的实现 1.ISO和TCP/IP分层模型&#xff1a; OSI分层模型&#xff08;Open System …

学成在线--12.Spring整合RibbitMQ

文章目录一.搭建SpringBoot环境二.配置1.配置application.yml2.定义RabbitConfig类三.生产端四.消费端一.搭建SpringBoot环境 我们选择基于Spring-Rabbit去操作RabbitMQ 使用spring-boot-starter-amqp会自动添加spring-rabbit依赖&#xff0c;如下&#xff1a; <dependenc…

一网打尽中文编码转换---6种编码30个方向的转换

一网打尽中文编码转换——6种编码30个方向的转换 1.问题提出 在学编程序时&#xff0c;曾经有人问过“你可以编一个记事本程序吗?”当时很不屑一顾&#xff0c;但是随着学习MFC的深入&#xff0c;了解到记事本程序也并非易事&#xff0c;难点就是四种编码之间的转换。 对于编…

安装Ubunutu音频视频库

sudo apt-get install ubuntu-restricted-extras转载于:https://www.cnblogs.com/or2-/p/9216235.html

十万服务器秒级管控 腾讯云如何将AIOps用于日常管理?

AIOps&#xff0c;是指基于算法的 IT运维&#xff08;Algorithmic IT Operations&#xff09;&#xff0c;由 Gartner定义的新类别&#xff0c;源自业界之前所说的 ITOA&#xff08;IT Operations and Analytics&#xff09;。我们已经到达了这样的一个时代&#xff0c;数据科学…

ssm(springMVC + spring+MyBatis) 小例

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 整体环境参见本人另一文&#xff1a;http://blog.csdn.net/jiangyu1013/article/details/51983360 此工程访问入口为index.jsp页面. 工…

多值依赖

在关系模式中&#xff0c;函数依赖不能表示属性值之间的一对多联系&#xff0c;这些属性之间有些虽然没有直接关系&#xff0c;但存在间接的关系&#xff0c;把没有直接联系、但有间接的联系称为多值依赖的数据依赖。例如&#xff0c;教师和学生之间没有直接联系&#xff0c;但…

js控制语句练习(回顾)

1、一个小球从100米空中落下&#xff0c;每次反弹一半高度&#xff0c;小球总共经过多少米&#xff0c;请问第10次反弹的高度是多少&#xff1f; //定义初始下落过程高度 var sum1 0; //定义初始上升高度 var sum2 0; //高度变化 var hight 100; for(var i0;i<10;i){ // …

学成在线--13.RabbitMQ工作模式

文章目录一.Work queues二.Publish/subscribe1.工作模式2.代码1&#xff09;生产者2&#xff09;消费者3.测试4.思考三.Routing1.工作模式2.代码1&#xff09;生产者2&#xff09;消费者3.测试4.思考四.Topics1.工作模式2.代码1&#xff09;生产者2&#xff09;消费者3.测试4.思…

《C++字符串完全指南——第一部分:win32 字符编码》

《C字符串完全指南--第一部分:win32 字符编码》 原作者:Michael Dun 译 者:Dingqiao Wang 引言 毫无疑问&#xff0c;你肯定见过像TCHAR, std::string, BSTR等等这类字符串类型.也包括一些以_tcs开头的奇怪的宏。也许你正盯着屏幕"哇哇"的发愁&#xff0c;然…

Spring、Spring MVC、MyBatis整合文件配置详解

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 web.xml的配置 web.xml应该是整个项目最重要的配置文件了&#xff0c;不过servlet3.0中已经支持注解配置方式了。在servlet3.0以前每…

19.C++-(=)赋值操作符、初步编写智能指针

()赋值操作符 编译器为每个类默认重载了()赋值操作符默认的()赋值操作符仅完成浅拷贝默认的赋值操作符和默认的拷贝构造函数有相同的存在意义()赋值操作符注意事项 首先要判断两个操作数是否相等 返回值一定是 return *this; 返回类型是Type&型,避免连续使用后,出现bug 比如…

windows mysqldump 不成功 1049 1064 报错

1064 路径不对&#xff0c;需要cd选到mysql bin目录下 1049 在cmd里面不需要分号 以下是正确的 E:\phpStudy\PHPTutorial\MySQL\bin>mysqldump -uroot -proot db >db.sql 转载于:https://www.cnblogs.com/JANCHAN/p/9227388.html

学成在线--14.使用RabbitMQ完成页面发布

文章目录一.技术方案二.页面发布——消费方1.需求分析2.创建Cms Client工程1&#xff09;创建maven工程2&#xff09;配置文件3&#xff09;启动类3.RabbitmqConfig配置类4.定义消息格式5.PageDao1&#xff09;使用CmsPageRepository 查询页面信息2&#xff09;使用CmsSiteRepo…

对象模型中类与类间的关系

类与类之间通常有关联、聚集、泛化(继承)、依赖和细化4种关系 1.关联 关联表示两个类的对象之间存在某种语义上的联系。 (1) 普通关联 只要在类与类之间存在连接关系就可以用普通关联表示。普通关联的图示符号是连接两个类之间的直线&#xff0c;如下图所示。关联…