冒泡排序(英语:Bubble Sort)是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
冒泡排序算法的运作如下:
如下的数据,我们从左到右开始,先将相邻的两个元素比较,依次往右边移动比较,最终能找到所有数据里面最大的,如下图所示:
- 第一轮排序,找到最大值的位置需要排列到索引为n-1的位置(n为所有元素的数量)。
- 下一轮,我们就可以从索引为0开始,直到n-2之间做相邻2个比较了
- 最后一轮是index=1的元素,比较n-1次,就你能确定n个元素的排序位置了
# 如果我们只比较一轮,把最大的值放到列表最右边,可以如下方式
n = len(mylist)
for i in range(n-1):
if mylist[i] > mylist[i+1]:
mylist[i], mylist[i+1] = mylist[i+1], mylist[i]
# 比较是从左向右开始比较的,但是最大值是放在最右边的
def bubble_sort(myList):
n = len(myList)
for j in range(n-1,0,-1): # 代表从最后一个元素向左到第二个元素,不包含index=0
for i in range(j): # j代表其他需要比较的元素的索引,数量逐步减少
if myList[i] > myList[i+1]:
myList[i], myList[i+1] = myList[i+1], myList[i]
myList = [54,26,93,17,77,31,44,55,20]
bubble_sort(myList)
print(myList)
# [17, 20, 26, 31, 44, 54, 55, 77, 93]
最外面循环,代表找到每轮最大值的索引,从最右边,一直正数第二个元素,对应range(n-1, 0, -1)
里面循环,代表从第一个元素,到最大元素前面的那个元素,所以用rang(0, j)表示
def maoPao_min(alist):
n = len(alist)
for i in range(0, n - 1):
for j in range(i + 1, n):
if alist[i] > alist[j]:
alist[j], alist[i] = alist[i], alist[j]
# [17, 20, 26, 31, 44, 54, 55, 77, 93]
def maoPao_min(alist):
n = len(alist)
for i in range(0, n - 1):
isSorted = False
for j in range(i + 1, n):
if alist[i] > alist[j]:
alist[j], alist[i] = alist[i], alist[j]
isSorted = True
print("every time ", alist)
if not isSorted:
break
print("result", alist)
myList = [17, 19, 21, 44, 54, 93]
maoPao_min(myList)
# every time [17, 19, 21, 44, 54, 93]
# result [17, 19, 21, 44, 54, 93]
当排序到某个位置的时候,后面的所有其他元素排序都排好了。那么循环的话,一次都不需要置换元素,这种情况我们可以做个判断,直接跳过所有循环即可
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下:
选择排序的主要优点:
- 每次循环一遍,比较完所有元素之后,找到最小(大)值之后,才会互换位置,否者不会互换位置
- 如果某个元素位于正确的最终位置上,则它不会被移动
- 如果列表为n个元素,那么所有元素最多进行n-1次交换(每个元素都换到非自己本身的位置)
- 如果所有元素都需要移动位置,选择排序属于非常好的一种
alist = [54, 226, 93, 17, 77, 31, 44, 55, 20]
def choiceSort(alist):
n = len(alist)
min_index = 0 # 假设最左边为最小值
for i in range(1, n): # 需要拿最小索引右边的所有元素与假设的比较
if alist[min_index] > alist[i]:
min_index = i
if min_index != 0:
alist[min_index], alist[0] = alist[0], alist[min_index]
choiceSort(alist)
print(alist)
# result [17, 226, 93, 54, 77, 31, 44, 55, 20]
alist = [54, 226, 93, 17, 77, 31, 44, 55, 20]
def choiceSort(alist):
n = len(alist)
max_index = n-1 # 假设最右边为最大值的索引
for i in range(n - 2, -1, -1): # 需要拿倒数第二个索引,从右向左比较,直到第一个索引
if alist[max_index] < alist[i]:
max_index = i
if max_index != n-1:
alist[max_index], alist[n-1] = alist[n-1], alist[max_index]
choiceSort(alist)
print(alist)
# result [54, 20, 93, 17, 77, 31, 44, 55, 226]
注意点:
- 从左到右找的时候,第二个索引到最后一个索引的表达式:range(2,n-1)
- 从右向左找的时候,倒数第二个索引,到正数第一个索引的表达式:range(n-2,-1,-1)
def selection_sort(alist):
n = len(alist)
# 需要进行n-1次选择操作
for i in range(n-1):
min_index = i # 记录最小位置
for j in range(i+1, n): # 从i+1位置到末尾选择出最小数据
if alist[j] < alist[min_index]:
min_index = j
if min_index != i:
alist[i], alist[min_index] = alist[min_index], alist[i]
alist = [54,226,93,17,77,31,44,55,20]
selection_sort(alist)
print(alist)
# [17, 20, 31, 44, 54, 55, 77, 93, 226]
def selection_sort(alist):
n = len(alist)
# 需要进行n-1次选择操作
for i in range(n - 1, 0, -1):
max_index = i # 记录最大值的索引
for j in range(i - 1, -1, -1): # 从i-1位置到起始位置选择出最大值索引
if alist[j] > alist[max_index]:
max_index = j
# 如果选择出的数据不在正确位置,进行交换
if max_index != i:
alist[i], alist[max_index] = alist[max_index], alist[i]
selection_sort(alist)
print(alist)
# [17, 20, 31, 44, 54, 55, 77, 93, 226]
注意点:
从左到右假设最小值索引的时候:0--------n-2, 对应range(n-1),到倒数第二个元素
此时,需要与其比较的其他数据的索引为:0+1------------n-1,对应的range(1, n)从第二个元素到最后一个元素
从右向左排序的时候,假设最右边为最大值索引,n-1----------1,对应range(n-1, 0, -1)
此时,需要比较的其他元素的索引为:n-2--------0,对应的range(n-2, -1, -1)