写在前面!
排序的稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的。
冒泡排序(稳定)
def bubble_sort(alist):
'''冒泡排序'''
n = len(alist)
for j in range(0,n-1):
for i in range(0,n-1-j):
if alist[i] > alist[i+1]:
alist[i],alist[i+1] = alist[i+1],alist[i]
时间复杂度为O(N^2),优化操作,当排序到某一时间段,已经全部有序了,就不用往下继续操作直接退出就好了。
具体做法是:加入一个计数变量,若在某一次遍历中,没有发生次序的交换操作,则直接退出
def bubble_sort(alist):
'''冒泡排序'''
n = len(alist)
for j in range(0,n-1):
count = 0
for i in range(0,n-1-j):
if alist[i] > alist[i+1]:
alist[i],alist[i+1] = alist[i+1],alist[i]
count += 1
if count == 0:
return
时间复杂度为O(n^2),优化之后最优情况的时间复杂度是O(N).
选择排序(先找最大的不稳定,先找最小的好像是稳定的?)
将第一个元素与依次和后面的元素进行比较,获取最小元素的下标min_index,再将list[0] 与 list[min_index] 互换位置,将最小的元素放在最前面,然后用第2个元素往后比较,得到从第二各元素开始最小值的下标min_index,再将list[1] 与 list[min_index] 互换位置,得到第二小的元素,循环往复依次排序。
def select_sort(alist):
'''选择排序'''
n = len(alist)
for j in range(0,n-1):# 产生0到n-2
min_index = j
for i in range(j,n):
if alist[min_index] > alist[i]:
min_index = i
alist[j],alist[min_index] = alist[min_index],alist[j]
时间复杂度O(n^2),最有情况下时间复杂度还是O(n^2)
插入算法(稳定)
将左边的第一个元素与后面的元素分开,左边的一个元素当然是有序的,将第二元素取出,与左边的一个元素比较,若第二个元素比第一个元素小,则第二的元素放置于第一个元素之前,随后将第三个元素取出,与左边的元素从后往前比较,依次排序。
def insert_sort(alist):
n = len(alist)
for j in range(1,n):
i = j
while i >0:
if alist[i] < alist[i-1]:
alist[i],alist[i-1] = alist[i-1],alist[i]
i -= 1
else:
break
上面如果没有break的话,当带插入的数是最大的时候,程序依旧会往前判断,没有进行优化,有了break就进行了优化。
最坏时间复杂度:O(n^2),
最优时间复杂度O(n)
希尔排序
def shell_sort(alist):
'''shell排序'''
# n = 9
n = len(alist)
# gap = 4
gap = n // 2
while gap > 0:
for j in range(gap,n):
i = j
while i - gap >= 0 :
if alist[i] < alist[i-gap]:
alist[i],alist[i-gap] = alist[i-gap],alist[i]
i -= gap
else:
break
gap //= 2
归并排序
def merge_sort(alist):
n =len(alist)
if n<= 1:
return alist
mid = n//2
# left 是指使用归并排序后形成的有序的新的列表
left_list = merge_sort(alist[:mid])
# right 是指使用归并排序后形成的有序的新的列表
right_list = merge_sort(alist[mid:])
# 将两个有序的子序列合并为一个整体
# 合并left and right
l_point,r_pointer = 0,0
result = []
while l_point < len(left_list) and r_pointer < len(right_list):
if left_list[l_point] < right_list[r_pointer]:
result.append(left_list[l_point])
l_point += 1
else:
result.append(right_list[r_pointer])
r_pointer += 1
result += left_list[l_point:]
result += right_list[r_pointer:]
return result
快速排序