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) 将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮 ...
随机推荐
- leetcode 1041. 困于环中的机器人
题目地址 : https://leetcode-cn.com/problems/robot-bounded-in-circle/ 在无限的平面上,机器人最初位于 (0, 0) 处,面朝北方.机器人可以 ...
- verilog 基础知识
mealy型状态机的下一状态和输出取决于当前状态和当前输入: moore型状态机的下一状态和输出取决于当前状态和当前输入,但其输出仅取决于现在的状态: 基本门原语的输出端口必须写在端口列表的前面,基本 ...
- java图形界面 计算器实现
编写程序实现一个简单计算器的基本功能,具体可以模仿Windows附件中的计算器或模拟常见的实物计算器. package beizi; import java.awt.EventQueue; impor ...
- Rust对协程的思考
最近和同事聊起来,觉得lua缺乏编译型语言的类型校验功能,还有变量拼写检查之类的,导致线上总是有低级错误出现.比如最近有一个是变量名拼写少了一个字母,导致某功能没开启:还有一个是变量传参时,之前测试多 ...
- springboot with appache sharding 3.1 单库分表
配置文件相关信息: #开发 server.port=7200 spring.application.name=BtspIsmpServiceOrderDev eureka.client.service ...
- win10 关闭 “在时间线中查看更多日期” 提示
在组策略中,禁用允许上传用户活动
- Web前端基础(7):JavaScript(一)
1. JavaScript概述 1.1 JavaScript历史背景介绍 布兰登 • 艾奇(Brendan Eich,1961年-),1995年在网景公司,发明的JavaScript. 一开始Java ...
- json字符串转为php数组,使用随机字符串生成订单号(学生笔记)
//提交订单 function add_order(){ session_start(); // var_dump($_SESSION); // die(); // session_destroy() ...
- uni-app学习(四)好用的插件2
1. uni-app学习(四)好用的插件2 1.1. 树形结构 点击这里 1.2. 下拉刷新上拉加载组件 如果想把下拉上拉做成自定义的,更加好看,可以使用这个插件 地址这里 举个例子 1.3. 浮动键 ...
- qt构建错误: dependent "*.h" does not exist.
项目中需要维护一套qt工程,今天发现一个头文件名称中单词拼写错误,就改正了,结果重新构建提示: dependent "*.h" does not exist. 原因:修改了文件后, ...