冒泡排序(Bubble Sort)
冒泡排序会对相邻的每两个元素进行比较,当左侧元素大于右侧元素时,交换它们的位置。重复 n-1轮,直至完成排序。
def bubble_sort(array):
"""冒泡排序"""
n = len(array)
if n <= 1:
return
for i in range(n):
is_sorted = True # 有序标志
for j in range(n-i-1):
if array[j] > array[j+1]:
array[j], array[j+1] = array[j+1], array[j]
is_sorted = False # 有数据进行交换,不是有序的,标记为False
if is_sorted:
break
if __name__ == '__main__':
a = [2, 5, 3, 6, 1, 4] # 增加了is_sorted判断是否有序,外部for执行了5次完成排序
b = [1, 2, 3, 4, 5, 6] # 增加了is_sorted判断是否有序,外部for执行了2次完成排序
bubble_sort(a)
bubble_sort(b)
print(a)
print(b)
插入排序(Insert Sort)
插入排序将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,保证已排序区间数据一直有序。重复这个过程,直到未排序区间中元素为空,算法结束。
def insert_sort(array):
"""插入排序"""
n = len(array)
if n <= 1:
return
for i in range(1, n):
insert_value = array[i]
j = i - 1
while j >= 0 and insert_value < array[j]:
array[j + 1] = array[j]
j -= 1
array[j+1] = insert_value
if __name__ == '__main__':
a = [2, 5, 3, 6, 1, 4]
b = [1, 2, 3, 4, 5, 6]
insert_sort(a)
insert_sort(b)
print(a)
print(b)
选择排序(Select Sort)
选择排序每轮会从数组中找出最小元素,直接交换到左侧,并在左侧维护一个有序区,重复n-1轮,排序完成。
这种排序最大优势就是省去了多余元素的重复交换。劣势是它不是一个稳定的排序算法
def select_sort(array):
"""选择排序"""
n = len(array)
if n <= 1:
return
for i in range(n-1):
min_index = i
for j in range(i + 1, n):
if array[j] < array[min_index]:
min_index = j
if i != min_index:
array[i], array[min_index] = array[min_index], array[i]
if __name__ == '__main__':
a = [2, 5, 3, 6, 1, 4]
b = [1, 2, 3, 4, 5, 6]
select_sort(a)
select_sort(b)
print(a)
print(b)
执行效率,内存消耗、稳定性
最好时间复杂度 | 最坏时间复杂度 | 平均时间复杂度 | 原地排序 | 稳定排序 | |
---|---|---|---|---|---|
冒泡排序(Bubble Sort) | O(n) | O(n²) | O(n²) | 是 | 是 |
插入排序(Insert Sort) | O(n) | O(n²) | O(n²) | 是 | 是 |
选择排序(Select Sort) | O(n²) | O(n²) | O(n²) | 是 | 否 |
随机n值下,冒泡排序、插入排序、选择排序3种算法在不同n值下的所耗时间