Python 基础排序算法
冒泡排序(bubble sort)
思路
以升序为例:
从第一个数开始向后两两对比,将大的数一直向后移动,直至最大的数移到最后,再找第二大的数
最好情况:O(n)
一般情况:O(n^2)
最坏情况:O(n^2)
代码
import random
def bubble_sort(l):
for i in range(len(l) - 1):
exchange = False
for j in range(len(l) - 1 - i):
if l[j] > l[j + 1]:
l[j], l[j + 1] = l[j + 1], l[j]
exchange = True
if not exchange: # 如果一次循环中都没有交换,则说明已经排序完成,可以提前结束
break
if __name__ == '__main__':
data = list(range(1000))
random.shuffle(data)
bubble_sort(data)
print(data)
选择排序(selection sort)
思路
以升序为例:
从第一个位置开始向后寻找,找到最小的数,放在这个位置,之后向后移一个位置
时间复杂度
最好情况:O(n^2)
一般情况:O(n^2)
最坏情况:O(n^2)
代码
import random
def selection_sort(l):
for i in range(len(l) - 1):
min_num = i
for j in range(i + 1, len(l)):
if l[j] < l[min_num]:
min_num = j
if min_num != i:
l[i], l[min_num] = l[min_num], l[i]
if __name__ == '__main__':
data = list(range(1000))
random.shuffle(data)
selection_sort(data)
print(data)
插入排序(insertion sort)
思路
以升序为例:
将第一个数分为有序队列,后面为无序队列。从二个数开始,依次插入前面有序队列
时间复杂度
最好情况:O(n)
一般情况:O(n^2)
最坏情况:O(n^2)
代码
import random
def insertion_sort(l):
for i in range(1, len(l)):
tem = l[i]
j = i - 1
while j >= 0 and tem < l[j]:
l[j + 1] = l[j]
j -= 1
l[j + 1] = tem
if __name__ == '__main__':
data = list(range(1000))
random.shuffle(data)
insertion_sort(data)
print(data)
快速排序(quicksort)
Python 的 sort 时间复杂度为 O(nlogn),但是因为是 C 写的,所以会快
思路
以升序为例:
从第一个数开始,将其他数分成两部分,小于这个数的放在左边,大于这个数的放在右边,分出的左右两边分别继续执行。
时间复杂度
最好情况:O(nlogn)
一般情况:O(nlogn)
最坏情况:O(n^2)
代码
import random
def quick_sort(l, left, right):
if left < right:
mid = partition(l, left, right)
quick_sort(l, left, mid - 1)
quick_sort(l, mid + 1, right)
def partition(l, left, right):
tem = l[left]
while left < right:
# 一次循环左右各移动一位
while left < right and l[right] > tem:
# 当前位不需要换位置,指针向内移动一位,直至遇到需要换位置的位
right -= 1
l[left] = l[right] # 将右边需要换位置的换到左边(取出的数之前的位置)
while left < right and l[left] < tem:
left += 1
l[right] = l[left]
l[left] = tem
return left
if __name__ == '__main__':
data = list(range(1000))
random.shuffle(data)
quick_sort(data, 0, len(data) - 1)
print(data)
堆排序(heapsort)
思路
以升序为例:
借助最大堆(大根堆)的特性,依次取出堆中最大的数(根结点的数),再对堆进行调整
时间复杂度
最好情况:O(nlogn)
一般情况:O(nlogn)
最坏情况:O(nlogn)
代码
import random
def sift(l, low, high):
i = low # 指向父节点
j = 2 * i + 1 # 指向左节点
tem = l[i] # 获取父节点的值
while j <= high: # 如果子节点在堆中(有子节点)
if j < high and l[j] < l[j + 1]: # 有右节点且比左节点大
j += 1 # 指向右节点
if tem < l[j]: # 如果根结点小于子节点中较大的那个
l[i] = l[j] # 将较大的值放入父节点
i = j # 指向下一层树
j = 2 * i + 1
else:
break
l[i] = tem # 将循环开始时的父节点数据写入
def heap_sort(l):
n = len(l)
for i in range(n // 2 - 1, -1, -1):
sift(l, i, n - 1)
# 堆建好了
for i in range(n - 1, -1, -1): # i 指向堆堆最后
l[0], l[i] = l[i], l[0] # 将当前最大数移到最后,最后的数移到根结点
sift(l, 0, i - 1)
if __name__ == '__main__':
data = list(range(1000))
random.shuffle(data)
heap_sort(data)
print(data)
归并排序(merge sort)
思路
以升序为例:
由于将两个有序列表合并比较简单,所以将列表无限分割成仅有一个元素的有序列表,之后再合并
时间复杂度
最好情况:O(nlogn)
一般情况:O(nlogn)
最坏情况:O(nlogn)
代码
import random
def merge_sort(l, low, high):
if low < high:
mid = (low + high) // 2
merge_sort(l, low, mid) # 前半部分迭代
merge_sort(l, mid + 1, high) # 后半部分迭代
merge(l, low, mid, high) # 调整
def merge(l, low, mid, high):
"""
用于将两个有序列表进行合并
"""
i = low # 指向左边有序列表第一个元素
j = mid + 1 # 指向右边有序列表第一个元素
tem_l = [] # 临时列表,用于存放合并后列表
while i <= mid and j <= high:
# 当左右列表中都有元素时
if l[i] <= l[j]:
tem_l.append(l[i])
i += 1
else:
tem_l.append(l[j])
j += 1
while i <= mid:
# 当左边列表中有元素时,直接将剩下的元素全部插入临时列表
tem_l.append(l[i])
i += 1
while j <= high:
# 当右边列表中有元素时,直接将剩下的元素全部插入临时列表
tem_l.append(l[j])
j += 1
# 用排序完成的元素替代未排序的元素
l[low:high + 1] = tem_l
if __name__ == '__main__':
data = list(range(1000))
random.shuffle(data)
merge_sort(data, 0, len(data) - 1)
print(data)
希尔排序(Shell's sort)
思路
以升序为例:
将元素分为n组,每一组进行插入排序,再将每组元素增加直至所有元素都在一组中
时间复杂度
O((1 + τ)n)
一般情况:O(1.3n)
代码
import random
def shell_sort(l):
gap = len(l) // 2
while gap > 0:
for i in range(gap, len(l)):
tem = l[i]
j = i - gap # 指向同组前一个元素
while j >= 0 and tem < l[j]: # 存在前一个元素并且比当前元素大
l[j + gap] = l[j] # 将前一个元素移到后面一位
j -= gap # 指向前一个元素
l[j + gap] = tem
gap //= 2
if __name__ == '__main__':
data = list(range(1000))
random.shuffle(data)
shell_sort(data)
print(data)
Python 基础排序算法的更多相关文章
- python常见排序算法解析
python——常见排序算法解析 算法是程序员的灵魂. 下面的博文是我整理的感觉还不错的算法实现 原理的理解是最重要的,我会常回来看看,并坚持每天刷leetcode 本篇主要实现九(八)大排序算法 ...
- python 经典排序算法
python 经典排序算法 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.常见的内部排序算 ...
- Java面试宝典系列之基础排序算法
本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排 ...
- php四种基础排序算法的运行时间比较
/** * php四种基础排序算法的运行时间比较 * @authors Jesse (jesse152@163.com) * @date 2016-08-11 07:12:14 */ //冒泡排序法 ...
- Python之排序算法:快速排序与冒泡排序
Python之排序算法:快速排序与冒泡排序 转载请注明源地址:http://www.cnblogs.com/funnyzpc/p/7828610.html 入坑(简称IT)这一行也有些年头了,但自老师 ...
- python实现排序算法 时间复杂度、稳定性分析 冒泡排序、选择排序、插入排序、希尔排序
说到排序算法,就不得不提时间复杂度和稳定性! 其实一直对稳定性不是很理解,今天研究python实现排序算法的时候突然有了新的体会,一定要记录下来 稳定性: 稳定性指的是 当排序碰到两个相等数的时候,他 ...
- Java基础系列--基础排序算法
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9082138.html 一.概述 基础排序算法包括:桶排序.冒泡排序.选择排序.插入排序等 ...
- 6种基础排序算法java源码+图文解析[面试宝典]
一.概述 作为一个合格的程序员,算法是必备技能,特此总结6大基础算法.java版强烈推荐<算法第四版>非常适合入手,所有算法网上可以找到源码下载. PS:本文讲解算法分三步:1.思想2.图 ...
- 第四百一十五节,python常用排序算法学习
第四百一十五节,python常用排序算法学习 常用排序 名称 复杂度 说明 备注 冒泡排序Bubble Sort O(N*N) 将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮 ...
随机推荐
- 使用 github pages快速部署自己的静态网页
看见很多大神在Github Pages上部署Demo,感觉效果还不错,刚才自己也试了一下,发现其实并不难! 选择 github pages 的理由 使用零成本: github pages 集成在 gi ...
- 从Python安装到语法基础,这才是初学者都能懂的爬虫教程
Python和PyCharm的安装:学会Python和PyCharm的安装方法 变量和字符串:学会使用变量和字符串的基本用法 函数与控制语句:学会Python循环.判断语句.循环语句和函数的使用 Py ...
- es6入门7--Set Map数据结构
本文作为ES6入门第十三章的学习整理笔记,可能会包含少部分个人的理解推测,若想阅读更详细的介绍,还请阅读原文ES6入门 一.set数据结构 1.set不接受重复值 ES6新增了Set构造函数用于创建s ...
- 易飞ERP API接口调用DEMO
一.使用场景: 1.需要开放ERP数据给第三方系统对接,如APP手机端开发,MES,OA等: 2.接口按现在主流开发,restful风格,传JSON数据,跨平台,不限开发工具: 3.不限易飞ERP,支 ...
- SSD与HDD、HHD的区别
SSD与HDD.HHD的区别 HDD机械硬盘 SSD固态硬盘 HHD混合硬盘
- pandas 学习 第3篇:Series - 数据处理(应用、分组、滚动、扩展、指数加权移动平均)
序列内置一些函数,用于循环对序列的元素执行操作. 一,应用和转换函数 应用apply 对序列的各个元素应用函数: Series.apply(self, func, convert_dtype=True ...
- Git分布式版本控制器使用
前言: 使用Git版本控制器差不多有一年多的时间了,在这一年多的时间里对这个传说的的分布式版本控制工具有了一定的了解.在实战项目开发中,对关于如何在通过Git提交项目,以及如何使用Git命令对提交的文 ...
- 红黑树之 原理和算法详细介绍(阿里面试-treemap使用了红黑树) 红黑树的时间复杂度是O(lgn) 高度<=2log(n+1)1、X节点左旋-将X右边的子节点变成 父节点 2、X节点右旋-将X左边的子节点变成父节点
红黑树插入删除 具体参考:红黑树原理以及插入.删除算法 附图例说明 (阿里的高德一直追着问) 或者插入的情况参考:红黑树原理以及插入.删除算法 附图例说明 红黑树与AVL树 红黑树 的时间复杂度 ...
- 如何在GibHub上传自己的项目
如何上传项目至GinHub 准备好项目.在项目ssm-crud的目录下右击,点击Git Bash Here,打开git命令行. 在命令行中,输入git init,使项目文件夹加入git管理: 输入gi ...
- Vue中的组件及路由使用
1.组件是什么 组件系统是 Vue 的一个重要概念,因为它是一种抽象,允许我们使用小型.独立和通常可复用的组件构建大型应用.通常一个应用会以一棵嵌套的组件树的形式来组织: 1.1组件的声 ...