冒泡排序(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 基础排序算法的更多相关文章

  1. python常见排序算法解析

    python——常见排序算法解析   算法是程序员的灵魂. 下面的博文是我整理的感觉还不错的算法实现 原理的理解是最重要的,我会常回来看看,并坚持每天刷leetcode 本篇主要实现九(八)大排序算法 ...

  2. python 经典排序算法

    python 经典排序算法 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.常见的内部排序算 ...

  3. Java面试宝典系列之基础排序算法

    本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排 ...

  4. php四种基础排序算法的运行时间比较

    /** * php四种基础排序算法的运行时间比较 * @authors Jesse (jesse152@163.com) * @date 2016-08-11 07:12:14 */ //冒泡排序法 ...

  5. Python之排序算法:快速排序与冒泡排序

    Python之排序算法:快速排序与冒泡排序 转载请注明源地址:http://www.cnblogs.com/funnyzpc/p/7828610.html 入坑(简称IT)这一行也有些年头了,但自老师 ...

  6. python实现排序算法 时间复杂度、稳定性分析 冒泡排序、选择排序、插入排序、希尔排序

    说到排序算法,就不得不提时间复杂度和稳定性! 其实一直对稳定性不是很理解,今天研究python实现排序算法的时候突然有了新的体会,一定要记录下来 稳定性: 稳定性指的是 当排序碰到两个相等数的时候,他 ...

  7. Java基础系列--基础排序算法

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9082138.html 一.概述 基础排序算法包括:桶排序.冒泡排序.选择排序.插入排序等 ...

  8. 6种基础排序算法java源码+图文解析[面试宝典]

    一.概述 作为一个合格的程序员,算法是必备技能,特此总结6大基础算法.java版强烈推荐<算法第四版>非常适合入手,所有算法网上可以找到源码下载. PS:本文讲解算法分三步:1.思想2.图 ...

  9. 第四百一十五节,python常用排序算法学习

    第四百一十五节,python常用排序算法学习 常用排序 名称 复杂度 说明 备注 冒泡排序Bubble Sort O(N*N) 将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮 ...

随机推荐

  1. acwing 116. 飞行员兄弟

    地址  https://www.acwing.com/problem/content/118/ “飞行员兄弟”这个游戏,需要玩家顺利的打开一个拥有16个把手的冰箱. 已知每个把手可以处于以下两种状态之 ...

  2. luoguP3246 [HNOI2016]序列

    题意 这题很难想到用莫队去做,因为第一印象是这个没办法O(1)移动指针. 考虑从\([l,r]\)移动到\([l,r+1]\) (从\([l,r]\)移动到\([l-1,r]\)同理). 我们用ST表 ...

  3. [IDA]修改变量类型、删除变量名

    1. 双击变量 2. 按D转换类型(Word.Byte.Dword) 3. 按U删除变量名 4. 按N修改变量名

  4. Zabbix 数据清理

    目录 Zabbix 数据清理的一系列操作 一.问题 二.解决办法 Zabbix 数据清理的一系列操作 基本信息: Zabbix 版本 4.0.9 MySQL 版本 5.5 一.问题 我们将 Zabbi ...

  5. Elasticsearch 6.x版本全文检索学习之Search API

    Elasticsearch 6.x版本全文检索学习之Search API. 1).Search API,实现对es中存储的数据进行查询分析,endpoind为_search,如下所示. 方式一.GET ...

  6. Jsp学习笔记(2)——页面导航、表单、EL表达式

    页面导航 有两种跳转页面的方法.重定向和请求转发 两者区别: 请求转发(forward) 重定向(rerect) 请求服务次数 1 2 是否保留第一次请求request范围的属性 保留 不保留 地址栏 ...

  7. 自定义Visual Studio调试器中的对象显示方式

    你有没有盯着调试器窗口中的对象,并希望你可以通过其他类型的东西来查看这些对象?我当然有!扩展项目以确定每个人的身份可能会非常快速.理想情况下,通过特定的属性值快速定位它们会很棒.对我们来说幸运的是,V ...

  8. Entity Framework 基础操作(1)

    EF是微软推出的官方ORM框架,默认防注入可以配合LINQ一起使用,更方便开发人员. 首先通过SQLSERVER现在有的数据库类生产EF 右键->添加->新建项,选择AOD.NET实体数据 ...

  9. Windows Server 2012 R2更新(KB2919355)

    必须按以下顺序安装这些KB:clearcompressionflag.exe,KB2919355,KB2932046,KB2959977,KB2937592,KB2938439和KB2934018. ...

  10. HTML语法规范

    HTML语法规范 语法规范概述 HTML标签是由尖括号包围的关键词,例如<html> HTML标签通常是成对出现的,例如<html> 和</html> ,我们成为双 ...