总结各种排序算法以及Python代码的实现(全部默认是从小到大排序)
1 冒泡排序
思想:两个两个比较,大的往后走。
def bubble_sort(alist):
n = len(alist)
for i in range(n-1):#外层循环,每次循环都产生一个最大的数,放到最后
count = 0 #优化,如果当前数组是排好序的,就撤出循环。
for j in range(n-1-i):#每次都是到n-1-j
if alist[j] > alist[j+1]:
alist[j], alist[j+1] = alist[j+1], alist[j]
count += 1
if count == 0:
break
if __name__ == '__main__':
alist = [1,5,2,4]
print(alist)
bubble_sort(alist)
print(alist)
2 选择排序法
思想:首先在对列里选择最小的元素,存放在排列序列的起始位置,然后在剩余序列中继续寻找最小的元素,放在已经排序末尾,以此类推。
def select_sort(alist):
n = len(alist)
for i in range(n-1):#要寻找n-1次最小值
min_index = i
for j in range(i+1,n):
if alist[min_index] > alist[j]:
min_index = j
alist[min_index], alist[i] = alist[i], alist[min_index]
if __name__ == '__main__':
ali = [1,5,2,3]
print(ali)
select_sort(ali)
print(ali)
3 插入排序法
思想:把数组定义成2部分,一部分是已经排序好的数组,另外一部分是没有排序的,把没有排序的数依次插入到已经排好序的数组中
def insert_sort(alist):
n = len(alist)
for i in range(1,n): #外层循环n-1次,依次将后续的数字插入排好序的数组中
for j in range(i,0,-1):#从第二个数字开始依次往前插入
if alist[i] < alist[i-1]:
alist[i], alist[i-1] = alist[i-1], alist[i]
else:
break
if __name__ == '__main__':
ali = [1,5,2,3]
print(ali)
insert_sort(ali)
print(ali)
4 希尔排序
思想:是插入排序的一种,把数组以一定间隔分为几组,依次将每组对应的元素用插入法排序,当数组分成n组时,间隔为1时,此时正好是插入排序
[19,4,2,9,45,67,33,35]
19 9 33
4 45 35
2 67 对应行进行插入排序
def shell_sort(alist):
n = len(alist)
gap = n >> 2 #先设置gap
while gap > 0:
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__':
ali = [1,5,2,3]
print(ali)
shell_sort(ali)
print(ali)
5 快速排序
思想:将第一个元素作为标准进行比较,然后将数组分为2部分,一部分比该元素小,一部分比该元素大。将该元素放在中间,依次递归进行排序
def quick_sort(alist, first, last):
if first >= last:
return
mid_value = alist[first]
low = first
high = last
while first < last:
while first<last and alist[last] >= mid_value:
last -= 1
alist[first] = alist[last]
while first < last and alist[first] < mid_value:
first += 1
alist[last] = alist[first]
alist[last] = mid_value
quick_sort(alist, low, last - 1)
quick_sort(alist, last+1, high)
if __name__ == '__main__':
ali = [1,5,2,3]
n = len(ali)
print(ali)
quick_sort(ali,0,n-1)
print(ali)
6 归并排序
思想:分治法。先递归分解数组再合并数组。将数组分解最小之后,然后分解成2个有序数组,比较2个数组最前面的数,谁小就先取谁,相应指针后移一位,然后再比较,直至一个数组为空,然后把另一个数组剩余部分复制过来
def merge_sort(alist):
n = len(alist)
if n <= 1:
return alist
mid = n // 2
left_li = merge_sort(alist[:mid])
right_li = merge_sort(alist[mid:])
left_pointer = 0
right_pointer = 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__':
ali = [1,5,2,3]
print(ali)
print(merge_sort(ali))
几种算法的时间复杂度比较:
排序方法 | 平均情况 | 最好情况 | 最坏情况 | 辅助空间 | 稳定性 |
冒泡排序 | O(n2) | O(n) | O(n2) | O(1) | 稳定 |
选择排序 | O(n2) | O(n2) | O(n2) | O(1) | 不稳定 |
插入排序 | O(n2) | O(n) | O(n2) | O(1) | 稳定 |
希尔排序 | O(nlgn)~O(n2) | O(n1.3) | O(n2) | O(1) | 不稳定 |
堆排序 | O(nlgn) | O(nlgn) | O(nlgn) | O(1) | 不稳定 |
归并排序 | O(nlgn) | O(nlgn) | O(nlgn) | O(n) | 稳定 |
快速排序 | O(nlgn) | O(nlgn) | O(n2) | O(lgn)~O(n) | 不稳定 |