writer:lIcht email:lIcht.gzl@gmail.com Date: 2019.9.15
排序方法的是对数据处理必不可少的算法,主要的排序方法有冒泡排序、选择排序、插入排序、shell排序、快速排序、归并排序等。根据待处理的数据结构不同选择不同的排序方法不同处理数据的效率也会不同。排序方法的好坏可以用最坏时间复杂度以及最优时间复杂度来衡量。
xxxxxxxxxx
# 冒泡排序
# 最坏时间复杂度O(n^2)
# 最优时间复杂度O(n)
# 稳定
def bubble_sort(alist):
"""冒泡排序"""
for j in range(1, len(alist)):
count = 0
for i in range(0, (len(alist)-j)):
# 从头走到尾
if alist[i] > alist[i+1]:
alist[i], alist[i+1] = alist[i+1], alist[i]
count += 1
if count == 0: # 如果一次循环后没有任何元素交换(顺序已正确)则停止排序
return
if __name__ == "__main__":
li = [54, 26, 93, 17, 31, 55, 65, 30]
print(li)
bubble_sort(li)
print(li)
xxxxxxxxxx
# 选择排序
# 最坏时间复杂度O(n^2)
# 最优时间复杂度O(n^2)
# 不稳定
def select_sort(alist):
"""选择排序"""
for j in range(len(alist)-2):
min = j
for i in range(j+1, len(alist)):
if alist[min] > alist[i]:
min = i
alist[j], alist[min] = alist[min], alist[j]
if __name__ == "__main__":
li = [54, 26, 93, 17, 31, 55, 65, 30]
print(li)
select_sort(li)
print(li)
xxxxxxxxxx
# 插入排序
# 最坏时间复杂度O(n^2)
# 最优时间复杂度O(n)
# 稳定
def insert_sort(alist):
"""插入排序"""
for j in range(1, len(alist)):
i = j
while i > 0: # for i in range(j, 0, -1) i取值为[j, j-1, ..., 0] (range中 "-1" 参数为反向顺序取值)
if alist[i] < alist[i-1]:
alist[i], alist[i-1] = alist[i-1], alist[i]
i -= 1
else: # 优化,提升了最优时间复杂度
break
if __name__ == "__main__":
li = [54, 26, 93, 17, 31, 55, 65, 30]
print(li)
insert_sort(li)
print(li)
xxxxxxxxxx
# 希尔排序
# 最坏时间复杂度O(n^2)
# 最优时间复杂度,根据步长不同而不同
# 不稳定
def shell_sort(alist):
"""希尔排序"""
n = len(alist)
gap = n//2
# gap变化到0之前插入算法执行的次数
while gap > 0:
# 插入算法。与普通插入算法区别就是gap步长
for j in range(gap, n):
i = j
while i > 0:
if alist[i] < alist[i-gap]:
alist[i], alist[i - gap] = alist[i - gap], alist[i]
i -= gap
else:
break
# 缩短gap步长
gap //= 2
if __name__ == "__main__":
li = [54, 26, 93, 17, 31, 55, 65, 30]
print(li)
shell_sort(li)
print(li)
xxxxxxxxxx
# 快速排序(必须掌握)
# 最坏时间复杂度O(n^2)
# 最优时间复杂度O(nlogn)
# 不稳定
def quick_sort(alist, first, last):
"""快速排序"""
if first >= last:
return
mid_value = alist[first]
low = first
high = last
while low < high:
# high 左移动
while low < high and alist[high] >= mid_value:
high -= 1
alist[low] = alist[high]
# low 右移动
while low < high and alist[low] < mid_value:
low += 1
alist[high] = alist[low]
# 退出循环时 low=high
alist[low] = mid_value
# 递归方式对原有列表mid_value两边的两部分进行处理
quick_sort(alist, 0, low-1)
quick_sort(alist, low+1, 0)
if __name__ == "__main__":
li = [54, 26, 93, 17, 31, 55, 65, 30]
print(li)
quick_sort(li, 0, len(li)-1)
print(li)
xxxxxxxxxx
# 归并排序
# 最坏时间复杂度O(nlogn)
# 最优时间复杂度O(nlogn)
# 稳定
def merge_sort(alist):
"""归并排序"""
n = len(alist)
if n <= 1:
return alist
mid = n//2
# left right是采用归并排序后形成的新的有序列表
left_li = merge_sort(alist[:mid])
right_li = merge_sort(alist[mid:])
# 将两个有序的子序列合并为一个新的整体
left_pointer, right_pointer = 0, 0
result = []
while left_pointer < len(left_li) and right_pointer < len(right_li):
if left_li[left_pointer] < right_li[right_pointer]:
result.append(left_li[left_pointer])
left_pointer += 1
else:
result.append(right_li[right_pointer])
right_pointer += 1
result += left_li[left_pointer:]
result += right_li[right_pointer:]
return result
if __name__ == "__main__":
li = [54, 26, 93, 17, 31, 55, 65, 30]
print(li)
sorted_li = merge_sort(li)
print(sorted_li)