冒泡排序
冒泡排序是一种稳定的排序算法,及相同元素排序前后位置不发生调换,时间复杂度为O(n^2).
冒泡排序的核心思想如下:
依次比较相邻元素,若前者大于后者则交换位置后继续向后比较,若小于则直接继续向后比较
比如:对于ll=[8, 5, 4, 6]
- 1.第一轮比较,比较前
ll=[8, 5, 4, 6]
首先比较8和5,8大于5,交换位置,继续向后比较;由于位置交换,比较8和4,8大于4,交换位置,继续向后比较;由于交换位置,比较8和6,8大于6,交换位置,比较到最后一个元素,第一轮比较结束,总共比较了3次,即len(ll)-1次,此时ll=[ 5, 4, 6, 8]
,可以看出第一轮找出了最大的元素,并放在了列表最后。
- 2.第二轮比较,比较浅
ll=[5, 4, 6, 8]
首先比较5和4,5大于4,交换位置,继续向后比较;由于位置交换,比较5和6,2小于6,直接继续向后比较;比较6和8,6小于8,不做交换。这里可以发现,第一轮已经找出了最大元素8,无需在用6和8比较,所以比较的次数应该减去比较的轮数,即len(ll)-1-1次,2次。此时ll=[5, 4, 6,8]
,可以看出第二轮找出了第二大元素,放在倒数第二个位置。
- 3.第三轮比较,比较前
ll=[5, 4, 6,8]
首先比较5和4,5大于4,交换位置,继续向后比较。6和8位第二大和最大元素,无需比较,此时比较轮数为len(ll)-1-2次,即1次。可以看出第三轮找到了第三大元素,并放在倒数第三的位置上
由上可知,采用双重循环即可完成代码的编写。第一重循环保证相邻元素能两两相互比较,第二重循环保证比较的次数为len(ll)-1-比较轮数
。
详细代码如下:
#coding = "utf-8"
def bubble_sort(list):
"""冒泡排序,稳定"""
#倒数第二个元素和最后一个元素比较后一轮结束
#所以用len(list)-1
for j in range(len(list)):
#每轮比较的个数为len(list)-1在减去排好的个数,即已执行的轮数
for i in range(len(list)-j-1):
# 考虑排好序的序列,记录变换次数,没变换次数为0,直接返回
count = 0
if list[i]>list[i+1]:
list[i],list[i+1] = list[i+1],list[i]
count+=1
if 0 == count:
return
if __name__ =="__main__":
li = [9,4,6,2,7,8]
print(li)
bubble_sort(li)
print(li)
插入排序
插入排序也是一种稳定的排序算法,时间复杂度为O(n^2)。
插入排序核心思想如下:
将原始序列分为两部分,左边为有序序列,右边为原始序列,遍历时每次从原始序列挑选一个元素插入到左边有序序列的正确位置。
同理:对于ll=[8, 5, 4, 6]
- 1.第一次插入
第一次认为第一个元素8作为原始序列中的有序序列,挑选5与8比较,5小于8,交换位置,5与左边有序序列比较完毕,此时ll=[5, 8, 4, 6]
,开始下一次插入。
- 2.第二次插入
此时认为前两个元素为有序序列,挑选下一个元素4进行比较,4比8小,交换位置,再与5比较,4比5小,交换位置,4与左边的有序序列交换完毕,此时ll=[4, 5, 8, 6]
- 3.第三次插入
此时认为前三个元素为有序序列,挑选下一个元素6进行比较,6比8小,交换位置,继续比较6和5,6比5大,交换结束。此时遍历完成,ll=[4, 5, 6, 8]
由上可知采用双重循环即可完成代码,第一重循环进行元素遍历,第二重循环将遍历到的元素与左边有序序列中的元素依次比较,若小于则交换位置,若大于则停止比较,继续遍历。
完整代码如下:
# coding = 'utf-8'
def insertion_sort(list):
# 序列长度
n = len(list)
# 第一重循环,遍历序列元素
for j in range(n):
# 记录有序序列个数
i = j
# 第二重循环,依次比较有序序列,初始认为第一个元素为有序序列
while i > 0:
# 若小于则交换位置
if list[i] < list[i-1]:
list[i], list[i-1] = list[i-1], list[i]
i -= 1
# 不小于则停止交换
else:
break
if __name__ == "__main__":
li = [9, 5684, 6,22 ,2, 7, 8]
print(li)
insertion_sort(li)
print(li)
选择排序
选择排序是一种不稳定的排序算法,比如5652,交换后5和2的位置对调,导致相同元素位置前后发生变化。时间复杂度为O(n^2)。
选择排序核心思想如下:
将原始序列分成两部分,左边有序,右边为原始序列,每次寻找右边序列的最小值,交换至左边序列的末尾
选择排序过程比较简单,直接上代码:
def selection_sort(list):
#主循环进行n-1次,最后一个数n为最大值,不用循环
for j in range(len(list)-1):
#第一个值的下标最为最小下标
min_index = j
#从第j+1个值开始比较,若不是最小,则交换下标
for i in range(j+1,len(list)):
if list[min_index] > list[i]:
min_index = i
#自循环执行完一轮后,此时i为列表中最小值下标,将值交换
list[j], list[min_index] = list[min_index], list[j]
if __name__ =="__main__":
li = [9,4,6,2,7,8]
print(li)
selection_sort(li)
print(li)