本文用 Python 实现了插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序。
先整体看一下各个算法之间的对比,然后再进行详细介绍:
| 排序算法 | 平均时间复杂度 | 最好情况 | 最坏情况 | 空间复杂度 | 排序方式 | 稳定性 |
| — | — | — | — | — | — | — |
| 插入排序 | O(n²) | O(n) | O(n²) | O(1) | In-place | 稳定 |
| 冒泡排序 | O(n²) | O(n) | O(n²) | O(1) | In-place | 稳定 |
| 选择排序 | O(n²) | O(n²) | O(n²) | O(1) | In-place | 不稳定 |
| 快速排序 | O(n log n) | O(n log n) | O(n²) | O(log n) | In-place | 不稳定 |
| 希尔排序 | O(n log n) | O(n log n) | O(n log n) | O(1) | In-place | 不稳定 |
| 堆排序 | O(n log n) | O(n log n) | O(n log n) | O(1) | In-place | 不稳定 |
| 归并排序 | O(n log n) | O(n log n) | O(n log n) | O(n) | Out-place | 稳定 |
n:数据规模
In-place:占用常数内存,不占用额外内存
Out-place:占用额外内存
稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同
描述
时间复杂度为 O(n^2),是稳定的排序方法。
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序。
插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。
代码实现
-- coding: UTF-8 --
def insert_sort(lists):
插入排序 时间复杂度为 O(n^2)
count = len(lists)
for i in range(1, count):
key = lists[i]
j = i - 1
while j >= 0:
if lists[j] > key:
lists[j + 1] = lists[j]
lists[j] = key
j -= 1
return lists
if name == “main”:
test = [2, 5, 4, 6, 7, 3, 2]
print(insert_sort(test))
描述
时间复杂度为 O(n log n),是不稳定的排序方法。
希尔排序(Shell Sort)是插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。
该方法因 DL.Shell 于 1959 年提出而得名。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。
代码实现
-- coding: UTF-8 --
def shell_sort(lists):
希尔排序 时间复杂度是 O(n log n)
count = len(lists)
step = 2
group = int(count / step)
while group > 0:
for i in range(0, group):
j = i + group
while j < count:
k = j - group
key = lists[j]
while k >= 0:
if lists[k] > key:
lists[k + group] = lists[k]
lists[k] = key
k -= group
j += group
group = int(group / step)
return lists
if name == “main”:
test = [2, 5, 4, 6, 7, 3, 2]
print(shell_sort(test))
描述
时间复杂度是 O(n²), 是稳定排序算法。
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
代码实现
-- coding: UTF-8 --
def bubble_sort(lists):
冒泡排序 时间复杂度是 O(n²)
count = len(lists)
for i in range(0, count - 1):
for j in range(0, count - i - 1):
if lists[j] > lists[j + 1]:
lists[j], lists[j + 1] = lists[j + 1], lists[j]
return lists
if name == “main”:
test = [2, 5, 4, 6, 7, 3, 2]
print(bubble_sort(test))
描述
快速排序的时间复杂度是 O(n log n), 是不稳定排序算法。
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
代码实现
-- coding: UTF-8 --
def quick_sort(lists, left, right):
快速排序 时间复杂度是 O(n log n)
if left >= right:
return lists
key = lists[left]
low = left
high = right
while left < right:
while left < right and lists[right] >= key:
right -= 1
lists[left] = lists[right]
while left < right and lists[left] <= key:
left += 1
lists[right] = lists[left]
lists[right] = key
quick_sort(lists, low, left - 1)
quick_sort(lists, left + 1, high)
return lists
if name == “main”:
test = [2, 5, 4, 6, 7, 3, 2]
print(quick_sort(test, 0, len(test) - 1))
描述
选择排序的时间复杂度是 O(n²), 是不稳定排序算法。
基本思想:第 1 趟,在待排序记录 r1 ~ r[n] 中选出最小的记录,将它与 r1 交换;第 2 趟,在待排序记录 r2 ~ r[n] 中选出最小的记录,将它与 r2 交换;以此类推,第 i 趟在待排序记录 r[i] ~ r[n] 中选出最小的记录,将它与 r[i] 交换,使有序序列不断增长直到全部排序完毕。
代码实现
-- coding: UTF-8 --
def select_sort(lists):
选择排序 时间复杂度是 O(n²)
count = len(lists)
for i in range(0, count):
min = i
for j in range(i + 1, count):
if lists[min] > lists[j]:
min = j

感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的:
① 2000多本Python电子书(主流和经典的书籍应该都有了)
② Python标准库资料(最全中文版)
③ 项目源码(四五十个有趣且经典的练手项目及源码)
④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)
⑤ Python学习路线图(告别不入流的学习)
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
7万+

被折叠的 条评论
为什么被折叠?



