今天复习了一下数据结构与算法中排序内容,并用python3进行了部分算法实现,尽管简单,但是依然很有收获,分享一下。
冒泡排序
def bubble_sort(alist):
"""
冒泡排序:它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
"""
for i in range(1, len(alist)):
for j in range(0, len(alist)-i):
if alist[j] >= alist[j+1]:
alist[j], alist[j+1] = alist[j+1], alist[j]
# print(alist)
return alist
def bubble_sort_optimal(alist):
"""
优化:通过对交换次数进行一次统计,如果没有交换,说明当前数列有序,剩下的就不用遍历了
"""
for i in range(1, len(alist)):
count = 0
for j in range(0, len(alist)-i):
if alist[j] >= alist[j+1]:
alist[j], alist[j+1] = alist[j+1], alist[j]
count += 1
# print(alist)
if count == 0:
print("第 %d 次,发现已经是有序了" % i)
return alist
return alist
a = [2, 1, 4, 3, 9, 7, 5, 8, 6]
a1 = [2, 1, 4, 3, 9, 7, 5, 8, 6]
print("排序前:\n", a)
print("排序后:\n", bubble_sort(a))
print("优化后的排序:\n", bubble_sort_optimal(a1))
排序前:
[2, 1, 4, 3, 9, 7, 5, 8, 6]
排序后:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
第 4 次,发现已经是有序了
优化后的排序:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
选择排序
def selection_sort(alist):
"""
选择排序:每次从待排序的序列中找一个最大(小)的数放在序列的起始位置,直到全部待排序的元素排完
"""
for i in range(len(alist)-1):
min_index = i
for j in range(i + 1, len(alist)):
if alist[min_index] >= alist[j]:
min_index = j
alist[i], alist[min_index] = alist[min_index], alist[i]
return alist
a = [2, 1, 4, 3, 9, 7, 5, 8, 6]
a1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
a2 = [9, 8, 7, 6, 5, 4, 3, 2, 1]
print("排序前:\n", a)
print("排序后:\n", selection_sort(a))
排序前:
[2, 1, 4, 3, 9, 7, 5, 8, 6]
排序后:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
插入排序
def inserting_sort(alist):
"""
插排:将待排序序列的第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。
(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
"""
for i in range(1, len(alist)):
while i > 0:
if alist[i] < alist[i - 1]:
alist[i], alist[i - 1] = alist[i - 1], alist[i]
i -= 1
else:
break
return alist
a = [2, 1, 4, 3, 9, 7, 5, 8, 6]
a1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
a2 = [9, 8, 7, 6, 5, 4, 3, 2, 1]
print("排序前:\n", a)
print("排序后:\n", inserting_sort(a))
排序前:
[2, 1, 4, 3, 9, 7, 5, 8, 6]
排序后:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
希尔排序
def shell_sort(alist):
"""
希尔排序:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,
待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。
"""
gap = len(alist) // 2
while gap > 0:
# 插排
for i in range(gap, len(alist)):
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
return alist
a = [2, 1, 4, 3, 9, 7, 5, 8, 6]
a1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
a2 = [9, 8, 7, 6, 5, 4, 3, 2, 1]
print("排序前:\n", a)
print("排序后:\n", shell_sort(a))
排序前:
[2, 1, 4, 3, 9, 7, 5, 8, 6]
排序后:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
快排
def quick_sort(alist):
"""
快排:
1、从数列中挑出一个元素,称为 "基准"(pivot);
2、重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。
在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
3、递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
"""
# 递归退出的条件
if len(alist) <= 1:
return alist
# 业务处理
pivot = alist[len(alist) // 2]
left = [x for x in alist if x < pivot]
middle = [x for x in alist if x == pivot]
right = [x for x in alist if x > pivot]
# 递归
return quick_sort(left) + middle + quick_sort(right)
a = [2, 1, 4, 3, 9, 7, 5, 8, 6]
a1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
a2 = [9, 8, 7, 6, 5, 4, 3, 2, 1]
print("排序前:\n", a)
print("排序后:\n", quick_sort(a))
排序前:
[2, 1, 4, 3, 9, 7, 5, 8, 6]
排序后:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
归并排序
# 归并排序
def merge(left, right):
result = []
while left and right:
if left[0] <= right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0))
while left:
result.append(left.pop(0))
while right:
result.append(right.pop(0))
return result
def merge_sort(alist):
if len(alist) <= 1:
return alist
middle = len(alist) // 2
left = merge_sort(alist[:middle])
right = merge_sort(alist[middle:])
return merge(left, right)
a = [2, 1, 4, 3, 9, 7, 5, 8, 6]
print("排序前:\n", a)
print("排序后:\n", merge_sort(a))
排序前:
[2, 1, 4, 3, 9, 7, 5, 8, 6]
排序后:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
主要思想见下图:
计数排序
# 计数排序
def count_sort(alist):
max_val = max(alist)
buckets = [0] * (max_val + 1)
for i in alist:
buckets[i] += 1
print("计数数组buckets:", buckets)
count = 0
for j in range(max_val + 1):
for _ in range(buckets[j]):
alist[count] = j
count += 1
return alist
a = [1, 2, 3, 2, 1, 4, 2, 3, 4, 1, 2, 3, 4, 6, 8]
print("排序前:\n", a)
print("排序后:\n", count_sort(a))
排序前:
[1, 2, 3, 2, 1, 4, 2, 3, 4, 1, 2, 3, 4, 6, 8]
计数数组buckets: [0, 3, 4, 3, 3, 0, 1, 0, 1]
排序后:
[1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 6, 8]
骚操作
使用第三方库:pip install pygorithm,包含了基本所有常用的排序算法
from pygorithm.sorting import bubble_sort, bucket_sort, counting_sort, heap_sort, insertion_sort, merge_sort, quick_sort, selection_sort, shell_sort
print(bubble_sort.get_code()) # 显示冒泡排序的代码
a = [2, 1, 4, 3, 9, 7, 5, 8, 6]
print(bubble_sort.sort(a)) # 应用算法
print(bubble_sort.improved_sort(a)) # 改良的冒泡排序
print(bubble_sort.time_complexities()) # 时间复杂度
def sort(_list):
"""
Bubble Sorting algorithm
:param _list: list of values to sort
:return: sorted values
"""
for i in range(len(_list)):
for j in range(len(_list) - 1, i, -1):
if _list[j] < _list[j - 1]:
_list[j], _list[j - 1] = _list[j - 1], _list[j]
return _list
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Best Case: O(n), Average Case: O(n ^ 2), Worst Case: O(n ^ 2).
For Improved Bubble Sort:
Best Case: O(n); Average Case: O(n * (n - 1) / 4); Worst Case: O(n ^ 2)
最后,分享一个对排序算法的一个经典总结,希望大家的学习有帮助。
人生苦短,我用python!-_-