1.冒泡排序:列表每两个相邻的数,如果前面比后面大,则交换这两个数
一趟排序完成后,则无序区减少一个数,有序区增加一个数
代码关键点:趟,无序区范围
第0趟,无序区没有数
第1趟,无序区1个数
无序去范围:
第i趟,无序区有n-i个数,无序区范围为n-i-1(从0开始,指针不会指到最后一个数)
代码如下:
1 # 时间复杂度:O(n*n) 2 def bubble_sort(li): 3 for i in range(len(li)-1): # 第i趟 4 for j in range(len(li)-i-1): # 无序区范围,指针最多走到的位置 5 if li[j] > li[j+1]: 6 li[j],li[j+1] = li[j+1],li[j] 7 print(li) 8 9 li = [3,9,7,2,4,6,5,8] 10 print(li) 11 bubble_sort(li)
优化方法:如果在一趟结束后没有任何数变化,则可以结束掉接下来的循环
1 def bubble_sort(li): 2 for i in range(len(li)-1): # 第i趟 3 exchange = False 4 for j in range(len(li)-i-1): # 无序区范围,指针最多走到的位置 5 if li[j] > li[j+1]: 6 li[j],li[j+1] = li[j+1],li[j] 7 exchange = True 8 print(li) 9 if not exchange: 10 return 11 12 13 li = [3,9,7,2,4,6,5,8] 14 print(li) 15 bubble_sort(li)
2.选择排序:
方法一:
循环一个列表从中找到最小的数,然后将这个数添加到一个空列表中,最后将这个数从原列表中剔除掉
缺点:
1.增加了一个新列表,需要更多的内存
2.min和remove时间复杂度都是O(n),最后的时间复杂度是O(n*n)
代码如下:
1 def select_sort_simple(li): 2 li_new = [] 3 for i in range(len(li)): 4 min_val = min(li) 5 li_new.append(min_val) 6 li.remove(min_val) 7 return li_new 8 9 li = [3, 9, 7, 2, 4, 6, 5, 8] 10 print(select_sort_simple(li))
方法二:
1.一趟排序记录最小的数,放到第一个位置
2.在一趟排序记录列表无序区最小的数,放到第二个位置
......
3.算法关键点:有序区和无序区,无序区最小数的位置
代码如下:
1 def select_sort(li): 2 for i in range(len(li)-1): # 第i趟,最后一个数不需要选择了 3 min_loc = i # 把无序区第一个数当做最小的数来标记 4 for j in range(i,len(li)): 5 if li[j] < li[min_loc]: 6 min_loc = j 7 li[i],li[min_loc] = li[min_loc],li[i] # 将无序区第一个数换成最小的数 8 print(li) 9 10 li = [3, 9, 7, 2, 4, 6, 5, 8] 11 print(li) 12 select_sort(li)
3.插入排序:
初始时手里(有序区)只有一张牌
每次(从无序区)摸一张牌,插入到手里已有牌的正确位置
当有序区的数比摸到的牌大的时候并且有序区的下标不小于0的时候,将有序区的牌往后挪个位置
时间复杂度:O(n*n)
代码如下:
1 def insert_sort(li): 2 for i in range(1,len(li)): # i 表示摸到的牌的下标 3 temp = li[i] 4 j = i - 1 # j 指的是手里的牌的下标 5 while j >= 0 and li[j] > temp: 6 li[j+1] = li[j] 7 j -= 1 # 指针往前移 8 li[j+1] = temp 9 print(li) 10 11 li = [3, 9, 7, 2, 4, 6, 5, 8] 12 print(li) 13 insert_sort(li)