本文Python实现了直接插入排序、基数排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、希尔排序。
上篇来介绍前四种排序方式:
下篇:八大排序算法的实现(下)
描述
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,
假设有一组无序序列 R0, R1, … , RN-1。
(1) 我们先将这个序列中下标为 0 的元素视为元素个数为 1 的有序序列。
(2) 然后,我们要依次把 R1, R2, … , RN-1 插入到这个有序序列中。所以,我们需要一个外部循环,从下标 1 扫描到 N-1 。
(3) 接下来描述插入过程。假设这是要将 Ri 插入到前面有序的序列中。由前面所述,我们可知,插入Ri时,前 i-1 个数肯定已经是有序了。
所以我们需要将Ri 和R0 ~ Ri-1 进行比较,确定要插入的合适位置。这就需要一个内部循环,我们一般是从后往前比较,即从下标 i-1 开始向 0 进行扫描。
分析
平均时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:稳定
代码实现
def insert_sort(lists):
# 插入排序
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
描述
基数排序(以整形为例),将整形10进制按每位拆分,然后从低位到高位依次比较各个位。主要分为两个过程:
(1)分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中(比如53,个位为3,则放入3号桶中)
(2)收集,再将放置在0~9号桶中的数据按顺序放到数组中
重复(1)(2)过程,从个位到最高位(比如32位无符号整形最大数4294967296,最高位10位)
分析
平均时间复杂度:O(dn)(d即表示整形的最高位数)
空间复杂度:O(10n) (10表示0~9,用于存储临时的序列)
稳定性:稳定
代码实现
# encoding:utf-8
import math
def radix_sort(lists, radix=10):
# lists为整数列表,radix为基数
k = int(math.ceil(math.log(max(lists), radix)))
# math.ceil函数是对浮点数向上取整,math.log函数是返回自然对数
# 用K位数可以表示任意整数
bucket = [[] for i in range(radix)]
# K次循环
for i in range(1, k+1):
for j in lists:
bucket[j/(radix**(i-1)) % (radix**i)].append(j)
del lists[:]
# del用于删除list中的一个或几个元素
for each in bucket:
lists.extend(each) # 桶合并
bucket = [[] for i in range(radix)]
return lists
# encoding=utf-8
from random import randint
def randit_sort():
A = [randint(1, 99999999) for _ in xrange(9999)]
for k in xrange(8): #K表示位数
bucket = [ [] for _ in xrange(10)] #对10个桶进行标签
for j in A:
bucket[j / (10 ** k) % 10].append(j)
A = [a for b in S for a in b]
for i in A:
print i
randit_sort()
描述
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
分析
平均时间复杂度:O(n2)
空间复杂度:O(1)
稳定性:稳定
代码实现
def bubble_sort(lists):
# 冒泡排序
count = len(lists)
for i in range(0, count):
for j in range(i + 1, count):
if lists[i] > lists[j]:
lists[i], lists[j] = lists[j], lists[i]
return lists
描述
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
分析
平均时间复杂度:O(nlog2n)
空间复杂度:O(nlog2n)
稳定性:不稳定
代码实现
def quick_sort(lists, left, right):
# 快速排序
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