排序在计算机算法中非常常见也非常基础,不管是准备面试还是纯属兴趣,掌握它都很有必要。
- 选择排序
基本思想:预置list[i]为最小,逐个比较range(i,len(list))里的元素,找到最小元素的下标,和刚开始预置的list[i]交换;前部分作为有序区,后面部分作为无序区,知道遍历完所有无序区。
- 冒泡排序
基本思想:逐个比较相邻的元素,后者小,则进行交换,最终将最大的数(无序区局部最大值)推送到列表最后端(有序区)。
- 插入排序
基本思想:从第2个元素开始,将该元素插入到已排好的有序区内,即逐个和有序区数据比较,找到应该插入的位置,将有序区该位置后的元素均往后移一位,最后将该元素放入应该插入的位置。
代码示例如下:
# 2021.11.4
# 排序算法(代码中默认升序)
# 选择排序1
# 时间复杂度:O(N3)
# 非原地排序,空间复杂度高
def select_sort1(li):
new_li = []
for i in range(len(li)):
min_item = min(li)
new_li.append(min_item)
li.remove(min_item)
print(new_li)
return new_li
# 选择排序2:原地排序
# 时间复杂度:O(N2)
# 空间复杂度: O(1)
def select_sort2(li):
for i in range(len(li)-1):
min_index = i
for j in range(i, len(li)): # 无序区寻找最小值得下标
if li[min_index] > li[j]:
min_index = j
li[i], li[min_index] = li[min_index], li[i] # 将最小值和开始预置的最小值位置交换,补充到有序区
print(li)
# 冒泡排序
# 时间复杂度:O(N2)
# 空间复杂度: O(1)
def bubble_sort(li):
for i in range(len(li)-1):
for j in range(len(li)-1-i):
if li[j] > li[j+1]:
li[j], li[j+1] = li[j+1], li[j]
print(li)
# 插入排序
# 时间复杂度:O(N2)
# 空间复杂度: O(1)
def insert_sort(li):
for i in range(1, len(li)): # 摸牌次数n-1
tmp = li[i]
j = i - 1 # 手里牌的小标,即有序区的下标
while tmp < li[j] and j >= 0:
li[j+1] = li[j]
j -= 1
li[j+1] = tmp
print(li)
if __name__ == '__main__':
import random
li = [i for i in range(1, 10, 1)]
random.shuffle(li)
print(li)
insert_sort(li)