冒泡法与简单选择排序比较

冒泡法

  • 属于交换排序。两两比较大小,交换位置。

  • 如同水泡咕嘟咕嘟往上冒

  • 结果分为升序和降序排列

  • 升序

      n个数从左至右,编号从0开始到n-1,索引0和1的值比较,如果索引0大,则交换  
      两者位置,如果索引1大,则不交换。继续比较索引1和2的值将大值放在右侧。  
      直至n-2和n-1比较完,第一轮比较完成。第二轮从索引0比较到n-2,因为最右侧  
      n-1位置上已经是最大值了。依次类推,每一轮都会减少最右侧的不参与比较直  
      至剩下最后2个数比较。
    
  • 降序

     	与升序相反
    
代码如下:
import random
l1 = [random.randint(-20,20) for i in range(10)]
length = len(l1)
for i in range(length):
    count = 0
    for j in range(length-i-1):
        if l1[j] > l1[j+1]:
            l1[j],l1[j+1] = l1[j+1],l1[j]
            count += 1#交换次数
    if count == 0:#如果在一趟比较中,没有发生交换,则说明顺序已经排好了,后边不需在比较排序
        break
    print(l1)

简单选择排序

  • 属于选择排序。两两比较大小,找出极值(极大值或极小值)被放置在固定的位置,这个固定位置一般指的是某一端

  • 分为升序和降序排列

  • 降序

     n个数从左至右,索引从0开始到n-1,两两依次比较,记录大值索引,此轮所有  
     数 比较完毕,将大数和索引0数交换,如果大数就是索引1,不交换。第二轮,从  
     1开始比较,找到最大值,将它和索引1位置交换,如果它就在索引1位置则不交  
     换。依次类推,每次左边都会固定下一个大数。
    
  • 升序

     和降序相反
    

基本实现代码如下:

import random
l1 = [random.randint(-20,20) for i in range(10)]
length = len(l1)
print(l1)
for i in range(length-1):
   maxindex=i
   for j in range(i+1,length):
       if l1[j] > l1[maxindex]:
           maxindex = j
   if i != maxindex:
       l1[maxindex],l1[i] = l1[i],l1[maxindex]
print(l1)

优化一:二元选择排序,同时固定左边最大值和右边最小值,减少迭代元素的次数
代码如下:

import random
l1 = [random.randint(-20,20) for i in range(9)]
length = len(l1)
print(l1)
for i in range(length//2):#一次固定两个数,所以循环次数减半
    maxindex=i    
    minindex=i
    for j in range(i+1,length-i):#每次循环在两边各固定一个值,下次循环就只能两边各减去一个数
        if l1[j] > l1[maxindex]:
            maxindex = j    #在一次循环中同时找到最大值和最小值
        if l1[j] < l1[minindex]:
            minindex = j
    if maxindex != i:
        l1[maxindex],l1[i] = l1[i],l1[maxindex]#最大值放左边
        if minindex == i:
            minindex = maxindex#如果最大值刚好最小值交换了,那么最小值得索引就是最大值的索引
    if minindex != length-1-i:
        l1[minindex],l1[length-1-i] = l1[length-1-i],l1[minindex]#最小值放右边。
print(l1)

优化二:如果最大索引的值和最小索引的值相同,那么要么取值到最后了,要么剩下所有值都一样了。[1, 1, 1, 1, 1, 1, 1, 1, 2] 这种情况,找到的最小值索引是-2,最大值索引8,上面的代码会交换2次,最小值两个1交换是无用功,所以,增加一个判断。
代码如下:

import random
l1 = [random.randint(-20,20) for i in range(9)]
length = len(l1)
print(l1)
for i in range(length//2):#一次固定两个数,所以循环次数减半
    maxindex=i    
    minindex=i
    for j in range(i+1,length-i):#每次循环在两边各固定一个值,下次循环就只能两边各减去一个数
        if l1[j] > l1[maxindex]:
            maxindex = j    #在一次循环中同时找到最大值和最小值
        if l1[j] < l1[minindex]:
            minindex = j
    if l1[minindex] == l1[maxindex]:#如果最大索引的值和最小索引的值相同,那么要么取值到最后了,要么剩下所有值都一样了
        break
    if maxindex != i:#如果最大值索引和要换位置的索引一样,则不需交换。
        l1[maxindex],l1[i] = l1[i],l1[maxindex]#最大值放左边
        if minindex == i:
            minindex = maxindex#如果最大值刚好最小值交换了,那么最小值得索引就是最大值的索引
    if minindex != length-1-i and l1[minindex] != l1[length-1-i]:#如果最小值和右边值一样,则不需交换
        l1[minindex],l1[length-1-i] = l1[length-1-i],l1[minindex]#最小值放右边。
print(l1)

冒泡法与简单选择排序相比:

  • 都需要数据一轮轮比较
  • 冒泡法可以设定一个标记判断此轮是否有数据交换发生,如果没有发生交换,可以结束排序,如果发生交换,继续下一轮排序。简单选择排序没有办法知道当前轮是否已经达到排序要求
  • 时间复杂度都为O(n2)
  • 简单选择排序减少了交换次数,提高了效率,性能略好于冒泡法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值