动图讲解可以参考别人的一篇文章:十大排序算法(该文全长 14237 字,配有 70 张图片和动画,预计阅读时间 47 分钟,强烈建议通过电脑端进行阅读。)
包括:
冒泡排序
选择排序
插入排序
希尔排序
归并排序
快速排序
堆排序
计数排序
桶排序
基数排序
python代码实现
冒泡排序
思路是定义一个游标从一侧到另一侧,比较游标所指的位置,与下一个要指的位置比较大小,如果大小不一致,则两个数值互换,然后游标再向前推一位,依次这样比较,直到第一轮循环比出最大或最小值,然后开始下一轮循环,已经比出来的值不用参与下轮循环。
import random
def bubble_sort(alist):
for i in range(len(alist) - 1):
# j表示每次遍历需要比较的次数,j随循环次数增加而减小
for j in range(i + 1, len(alist)):
if alist[i] > alist[j]:
alist[i], alist[j] = alist[j], alist[i]
alist = [281, 981, 738, 355, 226, 911, 532, 77, 175, 723]
bubble_sort(alist)
print(alist)
选择排序
选出第某个位置的值,排出了前n-1个后,第n个一定是最大或最小值了,时间复杂度和冒泡一模一样,都是O(n2)。
def selection_sort(alist):
#需要进行n-1次选择操作
for i in range(len(alist)-1):
#i是列表的索引,默认alist[i]最小,往后找看有没有比他小的,然后替换
min_index = i
for j in range(i+1,len(alist)):
if alist[min_index]>alist[j]:
min_index = j
#如果循环完成后,指针的位置发生了变化,交换原指针和新指针位置的值
if min_index != i:
alist[i],alist[min_index]=alist[min_index],alist[i]
alist = [281, 981, 738, 355, 226, 911, 532, 77, 175, 723]
selection_sort(alist)
print(alist)
插入排序
插入排序原理从无序序列放入已构建好的有序序列中。依次进行扫描,找到相应的位置并插入,填坑
这个有序序列一开始是没有值的,是从原无序序列中拿过来的值,所以,拿过来n个,有序序列就有n个,下一次拿过来的数要比较的次数就是n次,插入之后变成n+1个长度,依次类推,直至最后有序列表的长度等于原无序列表的长度
而在我们的排序中,有序序列和无序序列都在同一个序列中,前半部分有序,后半部分无序,所以因为序列的连续性,只能从无序部分的第一个先放进有序序列的最后一个,然后依次向前比较,找到正确的位置,将该数插入。
def insert_sort(alist):
for i in range(1, len(alist)): # 第一个坑是0索引位
for j in range(i, 0, -1):
if alist[j - 1] > alist[j]:
alist[j], alist[j - 1] = alist[j - 1], alist[j]
return alist
alist = [281, 981, 738, 355, 226, 911, 532, 77, 175, 723]
result = insert_sort(alist)
print(result)
快速排序
快速排序是在一个序列中选出一个基准值(第一个,最后一个或者中间一个),将这个值取出来,然后让序列中的其他值与之比较,比它大的放在左边,比较小的放在右边,第一轮循环结束后序列结构是小值序列+基准值+大值序列,然后将两边的序列也照此操作。快速排序要用到递归
方法一:
def quick_sort(alist, start, end):
if start >= end:
return
mid = alist[start]
left = start
right = end
while left < right: # 左右指针是否交汇
# 右边的向左移
while left < right and alist[right] >= mid:
right -= 1
alist[left] = alist[right]
# 左边的右移
while left < right and alist[left] < mid:
left += 1
alist[right] = alist[left]
# 从循环退出时,left=right
alist[left] = mid
# 左边的排序
quick_sort(alist, start, left - 1)
# 右边的排序
quick_sort(alist, left + 1, end)
alis = [96, 33, 98, 34, 36, 82, 52, 5, 67, 79]
quick_sort(alis, 0, len(alis) - 1)
print(alis)
方法二:
def quick_sort(data):
if len(data)>1:
left = []
right = []
base_index = len(data)//2 #基准值索引
base_data = data[base_index] #基准值
data.remove(base_data)
for li in data:
if li>=base_data:
right.append(li)
else:
left.append(li)
return quick_sort(left) + [base_data] + quick_sort(right)
else:
return data
alist = [281, 981, 738, 355, 226, 911, 532, 77, 175, 723]
result = quick_sort(alist)
print(result)