排序 巩固
冒泡排序
'''
冒泡排序算法的运作如下:
比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
'''
def bubble_sort(lst):
for j in range(len(lst)-1,1,-1):
# j 为比较的次数,不断减少。每进行一次排序,最后面的 "最大的数" 就不断增加,所以需要排序的次数就越来越少
for i in range(j):
# 不包括j
if lst[i] > lst[i+1]:#如果前面的元素大于后面的元素
# 不断将最大的元素向后移
lst[i],lst[i+1] = lst[i+1],lst[i]
li = [54,26,93,17,77,31,44,55,20]
bubble_sort(li)
print(li)
希尔排序
'''
将数组列在一个表中,分别进行插入排序。先以步长为一半,列表。然后对每一列进行排序。
然后将排好序的,再按照步长为一半,列表进行排序。
最后进行插入排序
'''
def shell_sort(lst):
n = len(lst)
gap = n//2 #按照总长度的一半进行分列,然后进行 行排序
while gap > 0:
for i in range(gap,n):
j = i
#按照步长进行排序
while j>= gap and lst[j-gap] > lst[j]:#对索引位置进行有规律的使用
# j-gap表示每一列上的元素,j发生变化,列发生变化
lst[j-gap],lst[j] = lst[j],lst[j-gap]
j -= gap#向上一行
gap = gap//2#缩小比较的列的个数
lst = [54,26,93,17,77,31,44,55,20]
shell_sort(lst)
print(lst)
归并排序
'''
先递归分解数组,后合并数组
将数组分解最小之后,然后合并两个有序数组。
比较两个数组最前面的数,谁小就先取谁,
取了之后相应的指针就向后移一位,然后再比较,直到一个数组为空
最后把另一个数组的剩余部分添加过来
'''
def merge_sort(alist):
if len(alist) <= 1:
# 如果只有一个元素,则不需要进行排序,直接返回结果
return alist
# 二分分解
num = len(alist)//2
left = merge_sort(alist[:num])
right = merge_sort(alist[num:])
# 合并
return merge(left,right)
def merge(left, right):
'''合并操作,将两个有序数组left[]和right[]合并成一个大的有序数组'''
#left与right的下标指针
l, r = 0, 0
result = []
while l<len(left) and r<len(right):
if left[l] < right[r]:
# 当左面的第l个元素小于右面的第r元素时
result.append(left[l])#添加左面的第一个元素
l += 1#左面元素l +1
else:
result.append(right[r])#如果不大于,右面元素r +1
r += 1
result += left[l:]#如果左面还有没进行比较的元素、则全部添加到比较后的result内部
result += right[r:]
return result
alist = [54,26,93,17,77,31,44,55,20]
sorted_alist = merge_sort(alist)
print(sorted_alist)
快速排序
'''
通过一趟排序将要排序的数据分割成独立的两部分,
其中一部分的所有数据都比另一部分数据小,
再按此方法对这两部分分别进行快速排序。
步骤为:
从数列中挑出一个元素,称为"基准"(pivot),
重新排序数列,所有元素比基准值小的摆放在基准前面,
所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,
该基准就处于数列的中间位置。这个称为分区(partition)操作。
递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。
'''
def quick_sort(alist, start, end):
"""快速排序"""
# 递归的退出条件
if start >= end:
return
# 设定起始元素为要寻找位置的基准元素
mid = alist[start]
# low为序列左边的由左向右移动的游标
low = start
# high为序列右边的由右向左移动的游标
high = end
while low < high:
# 如果low与high未重合,high指向的元素不比基准元素小,则high向左移动
while low < high and alist[high] >= mid:
# mid是一开始的元素
high -= 1
# 将high指向的元素放到low的位置上
alist[low] = alist[high]
# 在while循环内部不断发生位置转换
# 如果low与high未重合,low指向的元素比基准元素小,则low向右移动
while low < high and alist[low] < mid:
low += 1#寻找最小元素的位置
# 将low指向的元素放到high的位置上
alist[high] = alist[low]
# 退出循环后,low与high重合,此时所指位置为基准元素的正确位置
# 将基准元素放到该位置
alist[low] = mid
# 对基准元素左边的子序列进行快速排序
quick_sort(alist, start, low-1)
# 对基准元素右边的子序列进行快速排序
quick_sort(alist, low+1, end)
alist = [54,26,93,17,77,31,44,55,20]
quick_sort(alist,0,len(alist)-1)
print(alist)
插入排序
'''
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,
找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,
需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
'''
def insert_sort(lst):
for i in range(1,len(lst)):
# 比较的次数
for j in range(i,0,-1):
# 需要比较的次数不断增加
# 需要插入的元素不断增加,i不断变大
if lst[j] < lst[j-1]:
lst[j],lst[j-1] = lst[j-1],lst[j]
lst = [54,26,93,17,77,31,44,55,20]
insert_sort(lst)
print(lst)
选择排序
'''
首先在未排序序列中找到最小(大)元素,
存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,
然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
'''
def selection_sort(lst):
n = len(lst)
for i in range(n-1):
for j in range(i+1,n):
# 未排序序列,i不断增加,为第一个未排序序列元素
min_index = i #先令 i 为 min_index
if lst[j] < lst[min_index]:
min_index = j #如果min_index大于j 则交换位置
if min_index != i: #min_index发生了变化,不是 i
lst[i],lst[min_index] = lst[min_index],lst[i]
lst = [54,226,93,17,77,31,44,55,20]
selection_sort(lst)
print(lst)
本文来自博客园,作者:CodeYaSuo,转载请注明原文链接:https://www.cnblogs.com/hany-postq473111315/p/14231843.html