本文用python实现插入排序,交换排序,选择排序,归并排序,基数排序。其中插入排序分直接插入排序与希尔排序, 交换排序分冒泡排序与快速排序, 选择排序分简单选择排序与堆排序。
1, 直接插入排序
- 时间复杂度:O(n²)
- 空间复杂度: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 key >= lists[j]:
break
lists[j+1] = lists[j]
lists[j] = key
j = j-1
return lists
if __name__ == '__main__':
lst = [2, 4, 3, 1, 1]
print(insert_sort(lst))
2, 希尔排序(缩小增量排序)
- 时间复杂度:O(n)
- 空间复杂度:O(n√n)
- 稳定性:不稳定
#!/usr/bin/env python3
#-*- coding:utf8 -*-
def shell_sort(lists):
count = len(lists)
step = count//2
while step > 0:
for i in range(step, count):
key = lists[i]
j = i
while j>= step and key < lists[j-step]:
lists[j] = lists[j-step]
j = j-step
lists[j] = key
step = step//2
return lists
if __name__ == '__main__':
lst = [2, 42, 3, 11, 1, 18, 22, 7]
print(shell_sort(lst))
3, 简单选择排序
- 时间复杂度:O(n²)
- 空间复杂度:O(1)
- 稳定性:不稳定
#!/usr/bin/env python3
#-*- coding:utf8 -*-
def select_sort(lists):
count = len(lists)
for j in range(count-1):
min = j #min index
for i in range(j+1, count):
if lists[i] < lists[min]:
min = i
lists[min], lists[j] = lists[j], lists[min]
return lists
if __name__ == '__main__':
lst = [2, 42, 3, 11, 1, 18, 22, 7]
print(select_sort(lst))
4, 堆排序
- 时间复杂度:O(nlog₂n)
- 空间复杂度:O(1)
- 稳定性:不稳定
#!/usr/bin/env python3
#-*- coding:utf8 -*-
import random
def max_heapify(heap, heap_size, root):
'''在堆中做结构调整,使得父节点大于子节点'''
left = 2*root + 1
right = left + 1
larger = root
if left < heap_size and heap[left] > heap[larger]:
larger = left
if right < heap_size and heap[right] > heap[larger]:
larger = right
if larger != root:
heap[larger], heap[root] = heap[root], heap[larger]
max_heapify(heap, heap_size, larger)
def build_max_heap(heap):
'''构造一个堆,将堆中数据重新排序'''
heap_size = len(heap)
for i in range((heap_size-1)//2, -1, -1):
max_heapify(heap, heap_size, i)
def heap_sort(heap):
# 根据列表建立最大根堆
build_max_heap(heap)
for i in range(len(heap)-1, -1, -1):
# 将堆中根节点与i节点对调 再调整前面len-1个节点
heap[0], heap[i] = heap[i], heap[0]
max_heapify(heap, i, 0)
if __name__ == '__main__':
a = [30, 50, 57, 77, 62, 78, 94, 80, 84]
print(a)
heap_sort(a)
print(a)
b = [random.randint(1,1000) for i in range(20)]
print(b)
heap_sort(b)
print(b)
5, 冒泡排序
- 时间复杂度:O(n²)
- 空间复杂度:O(1)
- 稳定性:稳定
#!/usr/bin/env python3
#-*- coding:utf8 -*-
def bubble_sort(lists):
size = len(lists)
i = 0
while i < (size-1):
for j in range(size-1, i, -1):
if lists[j] < lists[j-1]:
lists[j], lists[j-1] = lists[j-1], lists[j]
i += 1
return lists
if __name__ == '__main__':
lst = [2, 42, 3, 11, 1, 18, 22, 7]
print(bubble_sort(lst))
6, 快速排序
- 时间复杂度:O(nlog₂n)
- 空间复杂度:O(nlog₂n)
- 稳定性:不稳定
#!/usr/bin/env python3
#-*- coding:utf8 -*-
def quick_sort(lists, start, end):
if start < end:
# 基准数设置
base = lists[start]
# i 从前向后搜索 j 从后向前搜索
i = start
j = end
while i < j:
while (i<j) and (lists[j] >= base):
j -= 1
lists[i] = lists[j]
while (i < j) and lists[i] <= base:
i += 1
lists[j] = lists[i]
lists[i] = base
# 递归前后半区
quick_sort(lists, start, i-1)
quick_sort(lists, j+1, end)
return lists
if __name__ == '__main__':
lst = [2, 42, 3, 11, 1, 18, 22, 7]
print(quick_sort(lst, 0, len(lst)-1))
7, 归并排序
- 时间复杂度:O(nlog₂n)
- 空间复杂度:O(1)
- 稳定性:稳定
#!/usr/bin/env python3
#-*- coding:utf8 -*-
def merge(a, b):
c = []
i = j = 0
while i < len(a) and j < len(b):
if a[i] < b[j]:
c.append(a[i])
i += 1
else:
c.append(b[j])
j += 1
if i == len(a):
c += b[j:]
else:
c += a[i:]
return c
def merge_sort(lists):
if (len(lists)<=1):
return lists
middle = len(lists)//2
left = merge_sort(lists[:middle])
right = merge_sort(lists[middle:])
return merge(left, right)
if __name__ == '__main__':
lst = [2, 42, 3, 11, 1, 18, 22, 7]
print(merge_sort(lst))
8, 基数排序
- 时间复杂度:O(d(r+n))
- 空间复杂度:O(rd+n)
- 稳定性:稳定
#! /usr/bin/env python3
#-*-coding=utf-8-*-
#基于桶排序的基数排序
from random import randint
def RadixSort(list,d):
for k in range(d):#d轮排序
s=[[] for i in range(10)]#因为每一位数字都是0~9,故建立10个桶
'''对于数组中的元素,首先按照最低有效数字进行
排序,然后由低位向高位进行。'''
for i in list:
'''对于3个元素的数组[977, 87, 960],第一轮排序首先按照个位数字相同的
放在一个桶s[7]=[977],s[7]=[977,87],s[0]=[960]
执行后list=[960,977,87].第二轮按照十位数,s[6]=[960],s[7]=[977]
s[8]=[87],执行后list=[960,977,87].第三轮按照百位,s[9]=[960]
s[9]=[960,977],s[0]=87,执行后list=[87,960,977],结束。'''
s[i//(10**k)%10].append(i) # 977/10=97(小数舍去),87/100=0
list=[j for i in s for j in i]
return list
if __name__ == '__main__':
a=[54, 21, 42, 12, 30, 88, 50, 24, 63] # 最多是二位数,d取2
print(a)
a=RadixSort(a,2) # 将排好序的数组再赋给a!!!!
print(a)
感谢文档:
堆排序的python实现
归并排序详解(python实现)
快速排序
利用Python实现堆排序
八大排序算法的 Python 实现