01

冒泡排序


基本思想:循环比较两个数,大的数下沉,小的数上浮所以叫冒泡

步骤:

  1. 比较相邻两个数的大小,如果第二个数小就交换位置
  2. 从前往后依次比较,每一轮最后一组比较完成后,最大数会被排在末尾
  3. 重复上述过程。


图解:排序算法合集1:冒泡 选择 插入_时间复杂度

def bubbleSort(arr):
count = 0
for i in range(0, len(arr) - 1):
for j in range(0, len(arr) - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
count = count + 1
print("循环比较次数:{0}".format(count))
return arr

arr = [1, 2, 3, 4, 5, 7, 6]
print(bubbleSort(arr))


​循环比较次数:21​​​​[1, 2, 3, 4, 5, 6, 7]​


平均时间复杂度:O(n²)


空间复杂度:O(1),比较和交换数据,仅需要一个辅助存储空间


稳定性:冒泡排序是稳定算法,“6 7 6 2 8” 排序后两个“6”的相对位置不变

优化:

冒泡排序一定会进行arr.length-1次的循环比较,但一旦数据已经排好序,之后的比较是没意义的,因此我们设置标志位,跳过无意义的比较,优化算法。

def bubbleSort(arr):
count = 0
for i in range(0, len(arr) - 1):
flag = False # 标志位:未完成排序
for j in range(0, len(arr) - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
flag = True # 已完成排序
count = count + 1
if not flag:
break
print("循环比较次数:{0}".format(count))
return arr

arr = [1, 2, 3, 4, 5, 7, 6]
print(bubbleSort(arr))

输出结果:

​循环比较次数:6​​​​[1, 2, 3, 4, 5, 6, 7]​


02

选择排序


基本思想:每次找出最小的数,排到队头,直到排序完成


步骤:

  1. 首先从未排序数列中找到最小数,排到队头
  2. 从剩余数列这个继续找最小的数,排到队头
  3. 重复,直到所有的元素均排列完毕


图解:排序算法合集1:冒泡 选择 插入_时间复杂度_02

def selectionSort(arr):
for i in range(0, len(arr) - 1):
min = i
for j in range(i + 1, len(arr)):
if arr[j] < arr[min]:
min = j
if i != min:
arr[i], arr[min] = arr[min], arr[i]
return arr


arr = [3, 6, 2, 4, 2, 13, 9, 21, 11]
print(selectionSort(arr))


输出结果:

​[2, 2, 3, 4, 6, 9, 11, 13, 21]​


平均时间复杂度:O(n²)

空间复杂度:O(1),比较和交换数据,仅需要一个辅助存储空间


稳定性:选择排序是稳定算法,“6 7 6 2 8” 在第一次排序时,会将第一个位置的6和之后的2调换位置,此时两个6的相对位置已经改变。

03

插入排序


基本思想:会打扑克就会插入排序


排序算法合集1:冒泡 选择 插入_空间复杂度_03

步骤:

把数组第一个元素视为有序数列,将剩下的元素插入到有序数列。

图解:

排序算法合集1:冒泡 选择 插入_插入排序_04

def insertionSort(arr):
# 从数组第二个元素开始插入
for i in range(1, len(arr)):
current = arr[i] # 要插入的元素
preIndex = i - 1 # 从相邻的开始比较
while preIndex >= 0 and arr[preIndex] > current:
arr[preIndex + 1] = arr[preIndex]
preIndex = preIndex - 1 # 指针前进一格
arr[preIndex + 1] = current # 完成当前元素的插入
return arr


arr = [3, 6, 2, 4, 2, 13, 9, 21, 11]
print(insertionSort(arr))


输出结果:

​[2, 2, 3, 4, 6, 9, 11, 13, 21]​


平均时间复杂度:O(n²)
空间复杂度:O(1),比较交换数据,仅需要一个辅助存储空间


稳定性:插入排序是稳定算法,“6 7 6 2 8” 是相邻比较,排序后两个“6”的相对位置不变

04

总结


排序算法

平均时间复杂度

空间复杂度

稳定性

冒泡排序

O(n²)

O(1)

稳定

选择排序

O(n²)

O(1)

不稳定

插入排序

O(n²)

O(1)

稳定