一、排序算法
- 概念
排序算法(英语:Sorting algorithm)是⼀种能将⼀串数据依照特定顺序进⾏ 排列的⼀种算法。 - 稳定性
稳定排序算法会让原本有相等键值的纪录维持相对次序
(4, 1) (3, 1) (3, 7)(5, 6)
(3, 1) (3, 7) (4, 1) (5, 6) (维持次序)
(3, 7) (3, 1) (4, 1) (5, 6) (次序被改变)
二、冒泡排序
- 基本流程
- 从第一个元素开始, ⽐较相邻的元素。如果第⼀个⽐第⼆个⼤(升序,就交换他们两个。
- 较大值继续与后面元素进行比较,直到最后一个元素,然后将第一次遍历比较的最大值结果放到序列的最后
- 并从第一个元素开始,与相邻的进行比较,继续遍历所有元素,直到倒数第二个元素(此时,倒数第一个元素已经是最大值,无需进行比较),然后将第二次遍历比较的次最大值结果放到序列的倒数第二个位置
- 重复3步骤,寻找第三个最大值,并放到序列的倒数第三个位置,直到序列中只剩下一个元素(此时,剩下的这一个元素就是序列最小值,也不需移动)
- 注
- 基于以上分析,整个序列sort_list需要进行len(sort_list-1)次遍历(最后一次无需比较),即需遍历序列的次数为len(sort_list-1),每一次寻找出剩余序列中的最大值
- 序列中每一次遍历时剩余序列中元素的个数变化,len(sort_list-1) ->1,因为每次遍历寻找一次剩下序列的最大值,剩余序列中的元素个数就减1
- python实现
'''冒泡排序'''
def bubble_sort(sort_list):
l = len(sort_list) - 1
for i in range(l,0,-1): #每次选取最大值时需要比较元素个数
for j in range(i): # 选取最大值需要比较的次数
if sort_list[j] > sort_list[j+1]:
sort_list[j],sort_list[j+1] = sort_list[j+1],sort_list[j]
return sort_list
if __name__ == "__main__":
sort_list = [54,26,93,17,77,31,44,55,20]
print('排序前:',sort_list)
bubble_sort(sort_list)
print('排序后:',bubble_sort(sort_list))
运行结果
排序前: [54, 26, 93, 17, 77, 31, 44, 55, 20]
排序后: [17, 20, 26, 31, 44, 54, 55, 77, 93]
三、选择排序
-
基本思想
将需要排序的序列分为已排序序列和未排序序列,每次遍历未排序序列中的所有元素,相邻元素之间相互比较寻找出最小值,然后再将最小值移动到已排序序列的末尾,直到所有元素都移动到合适的位置 -
基本流程
- 第一遍遍历,默认需要排序序列中的第一个元素为已排序序列中的第一个元素,将已排序序列中的第一个元素与未排序序列中的其他元素相互比较,如果未排序序列中的最小值仍大于已排序序列中的最小值,则已排序序列中的元素不许移动,否则,将已排序序列中的最小值替换为未排序序列中的最小值
- 遍历未排序序列中剩余的元素,寻找次最小值,移动到已排序序列中的末尾
- 再次选择未排序序列中的第一个元素为最小值,再次拿最小值与剩余元素进行比较,将比较后得到的最小值移动到已排序序列中的末尾
- 重复3的步骤,当未排序序列中只剩下最后一个元素(此时,最后一个元素无需进行比较,也无需移动,就是需要排序序列中的最大值)
注
基于以上分析,需要遍历序列的次数为len(sort_list)-1次,最后一个元素无需比较
- python实现
def select_sort(sort_list):
'''选择排序'''
n = len(sort_list)
for j in range(n-1): # 寻找最小值的次数
min_index = j
for i in range(j,n): # 每次选择最小值索引后进行的比较次数
if sort_list[i] < sort_list[min_index]: # 一直跟踪alist[i],直到与最后一个元素比较完
sort_list[min_index],sort_list[i] = sort_list[i],sort_list[min_index]
# 每次默认无序中的第一个元素是最小值,即为有序序列,从后面的无序序列中寻找最小值交换位置,并插入到有序序列
sort_list = [52,41,25,31,89,56,33,64]
print('排序前',sort_list)
select_sort(sort_list)
print('排序后',sort_list)
四、插⼊排序
-
基本思想
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描, 找到相应位置并插⼊。插⼊排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插⼊空间。 -
基本流程
- 首先将序列中第一个元素做为有序序列中的第一个元素
- 遍历无序序列中的每一个元素,每遍历一个元素,将此元素与已排序序列中的元素按照从后往前的顺序进行比较,如果遇到合适的位置就插入到有序序列中
- 重复2的步骤,再次遍历无序序列中的第一个元素,将此元素与有序序列中的元素按照从后往前的顺序进行比较,遇到合适的元素就插入,直到无序序列中的最后一个元素也插入到有序序列中的合适位置为止
- python实现
def insert_sort(alist):
n = len(alist)
for j in range(1,n): # 总共需要插入有序序列的元素数(插入次数,默认第一个元素是有序的)
for i in range(j,1,-1): #每成功插入一个元素,需要进行的比较次数
if alist[i] < alist[i-1]: # 每次遍历的元素需和它的前一元素进行比较(每遍历一次就将元素放在有序元素的合适位置)
alist[i],alist[i-1] = alist[i-1],alist[i]
else:
break
alist = [52,41,25,31,89,56,33,64]
print('排序前',alist)
select_sort(alist)
print('排序后',alist)
六、快速排序
- 概念
通过⼀趟排序将要排序的数据分割成独⽴的两部分,其中⼀部分的 所有数据都⽐另外⼀部分的所有数据都要⼩,然后再按此⽅法对这两部分数 据分别进⾏快速排序,整个排序过程可以递归进⾏,以此达到整个数据变成有序序列 - 基本流程
- 从数列中挑出⼀个元素,称为"基准",一般选取序列的第一个元素为‘基准数,使用mid,low,hign分别指向序列中的基准值,较小值和较大值
- 从后往前遍历序列中的元素,使用hign指向移动,如果遇到比基准值大的元素,则hign指向不变,即位置不变,如果遇到比基准值小的元素,则将low指向该元素,即将该元素移动到基准值左边
- 再从前往后遍历序列中的元素,使用low指向移动,如果遇到比基准值小的元素,则low指向不变,即位置不变,如果遇到比基准值大的元素,则将hign指向该元素,即将该元素移动到基准值右边
- 重复2、3步骤,从后往前遍历序列,遇到比基准值小的元素,改变low的指向,将该元素移动到基准元素左边,再从前往后遍历,遇到比基准值大的元素,改变hign的指向,将该元素移动到基准元素右边
- python实现
def quick_sort(alist, start, end):
"""快速排序"""
if start >= end:
return
mid = alist[start]
left = start
right = end
# left与right未重合,就向中间移动
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相遇,即left==right
alist[left] = mid
# 对左边部分执行快速排序
quick_sort(alist, start, left-1)
# 对右边部分执行快速排序
quick_sort(alist, left+1, end)
if __name__ == '__main__':
li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
print(li)
quick_sort(li, 0, len(li)-1)
print(li)
七、希尔排序
八、归并排序
九、常见排序算法效率比较