博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
冒泡排序、选择排序、插入排序
阅读量:6601 次
发布时间:2019-06-24

本文共 2218 字,大约阅读时间需要 7 分钟。

在开始这三种算法的学习之前,我们要先来补给几个知识:

时间复杂度

时间复杂度:用来评估算法运行效率的一个式子

时间复杂度-小结:

快速地判断算法复杂度:

简单情况:

  • 确定问题规模n
  • 循环减半过程 -- logn
  • k层关于n的循环 n的k次方

复杂情况:根据算法执行过程判断

稳定性:

  相同值的情况下,排序完两个值的相对位置不会发生变化。

 

1、冒泡排序(Bubble Sort)

算法描述

比较相邻的两个元素,如果第一个比第二个大,就交换他们两个的位置。(每一趟都会冒出一个有序区的数。)

动图

 

代码实现

 
def bubble_sort(li):     # 第一层循环几趟     # len - 1,因为冒泡排序最后一趟的数字已经是最大的了,无需要再走一趟。     for i in range(len(li) - 1):         # 第二层循环,         # - i:在无序区中比较两个数的大小,每一趟结束之后会产生一个有序数字         # - 1:最后一个数字无须遍历,因为在第j次(倒数第二个数字)已经与j+1(倒数第一个数字)次进行了比较         exchange = False         for j in range(len(li) - i - 1):             if li[j+1] < li[j]:      # 升序                 li[j+1], li[j] = li[j], li[j+1]                 exchange = True         # 如果标志位没有变化,则说明这一趟中数字位置没有发生变化(即已经有序了),后面的趟没必要比较了         if not exchange:             return li = [1, 2, 5, 3, 4, 6, 9, 8, 7] bubble_sort(li) print(li) ##[1, 2, 3, 4, 5, 6, 7, 8, 9]

小结:

  • 选择排序时间复杂度:O的二次方
  • 原地排序
  • 比较时都是相邻的数进行比较(埃个比较),具有稳定性

2、选择排序(Selection Sort)

算法描述

每一趟选择一个数放在第一位,然后后面每个数都与这个数进行比较,如果比第一位数小的话就替换掉第一个数,然后后面的数再和新的最小值比较,一趟完成过后有序区产生一个有序数字,然后每一趟都循环无序区中的数字。

动图演示

代码演示

def select_sort(li):     # 第一层循环, 循环多少趟    # 每一趟拿出无序区中的第一个元素出来与后面无序的元素进行比较, 所以趟数为无序区中去掉第一个元素的长度     for i in range(1,len(li)):         min_sol = i         # 选择出第一个数,使后面每个数不断比较不断更新最小值,等走完一趟之后确定这趟的最小值,进行替换         for j in range(i+1, len(li)):             if li[j] < li[min_sol]:                 min_sol = j         if min_sol != i:             li[min_sol], li[i] = li[i], li[min_sol] li = [1, 2, 5, 3, 4, 6, 9, 8, 7] select_sort(li) print(li)

小结:

  • 时间复杂度也是n方
  • 原地排序
  • 排序时发现一个数比第一个数小,直接隔离很多数换去第一个位置(跳着换),不具有稳定性。比如:[2,3,2,1,4], 1和第一个2换了,两个2的相对位置发生了变化
  • 和冒泡排序的区别,稳定性和不稳定性,冒泡排序的无序区在每一趟后面,选择排序的无序区在每一趟前面。

3、插入排序(Insertion Sort)

算法描述

它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置插入。

实现思路:

  1. 从第一个元素开始,该元素可以认为已经被排序;
  2. 取出下一个元素,在已经排序的元素序列从后向前扫描
  3. 如果该元素大于新元素,则该元素移动到下一位置。

动图演示

 

 

代码实现

def insert_sort(li):    for i in range(1, len(li)):        j = i - 1   # j 为手里最大的牌     tmp = li[i]        while j >= 0 and li[j] > tmp:     # 只要手里最大的牌比摸回来的牌大就一致往右移动            # j >= 0 ,说明所有数都比摸到的牌要大,直接退出循环            li[j+1] = li[j]     # 右移            j -= 1        li[j+1] = tmp     # 确定要插入的时候,是必须插到j的前一个位置

 小结:

  • 时间复杂度:n方
  • 原地排序
  • 没有跳着(跳着无序区的数字)插入,所以具有稳定性。

转载于:https://www.cnblogs.com/Xuuuuuu/p/10804830.html

你可能感兴趣的文章
ubuntu下配置tomcat的步骤;
查看>>
python学习随笔--django 上
查看>>
安装WEB_shell开源堡垒机 gateone
查看>>
高性能HTTP加速器Varnish(安装配置)
查看>>
软件技术发展的几个阶段
查看>>
查看WINXP系统关机时间 so-easy
查看>>
修改mysql数据库编码
查看>>
代码审查RhodeCode试用
查看>>
我的友情链接
查看>>
squid代理服务器的控制功能详细配置
查看>>
MongoDB权威指南——入门
查看>>
mybatis设置一对多映射
查看>>
ubuntu 14.04编译安装openvas 8
查看>>
阳性水草与阴性水草的区分
查看>>
DIV+css命名规则
查看>>
Zookeeper 注册中心安装
查看>>
十一、RDS VDI 标准部署
查看>>
String StringBuffer StringBuilder
查看>>
通过路由器静态PAT访问FTP服务器测试
查看>>
自己需要读的书
查看>>