冒泡排序、选择排序、插入排序(python)

一:冒泡排序

原理:

(1)列表每两个相邻的数,如果前面比后面大,则交换这两个数。

(2)一趟排序完成后,则无序区减少一个数,有序区增加一个数。

(3)代码关键点:趟、无序区范围

 如上图所示,这是一个未排序的列表,冒泡排序的做法是从第0位开始,与它下一个数进行比较,如果前面比后面大,则交换这两个数,每次比较后再与下一个数比较,直到指针指到第7位时,与第8位进行比较之后,能成功得将最大的数排到了第8位也就是最后一位,此时将该列表分为有序区与无序区,如下图所示,有序区中的数为9,无序区的数为剩下的数。这样一个趟就可以使有序区的数增加一个。举下图为例,设 i 为第几趟,只需进行列表的长度减一(len(list)-1)趟就能成功排序,因为此时无序区只剩下一个数,而这个数是经过比较后剩下来最小的一个数,不需要再进行比较。

 j 指的是指针的位置,第i趟时,无序区有n - 1个数,

第0趟时指针最后指到的是第7位,第1趟时指针最后指到的是第6位,列表长度是9,所以指针指在n - i - 1处。(range顾头不顾尾)

def bubble_sort(list):
    for i in range(len(list) - 1):  ##总共排n-1趟
        exchange = False               #如果某一趟完成了不必继续进行排序
        for j in range(len(list)-i-1):    #第i趟时,无序区有n-i个数,指针指在n-i-1处
            if list[j] > list[j+1]:
                list[j],list[j+1] = list[j+1], list[j]
                exchange = True
        if not exchange:
            return

exchange开关是可以减少不必要的操作,如果某一趟完成了,没有再进行交换不必继续进行排序。

时间复杂度O(n2)

二:选择排序

原理:

(1)一趟排序记录最小的数,放到第一个位置

(2)再一趟排序记录无序区最小的数,放到第二个位置,以此类推

(3)算法关键点:有序区和无序区、无序区最小数的位置。

def select_sort(list):
    for i in range(len(list)-1):    ##i时第几趟
        min_value = i    ##无序区第一个数
        for j in range(i+1,len(list)):          ##第i趟无序区的第一个数为list【i】,从无序区第一个数开始和后面的数进行比较
            if list[j] < list[min_value]:
                min_value = j
        list[i],list[min_value] = list[min_value],list[i]

同理,只需进行n-1趟就能成功排序,先设无序区第一个数为最小值,再与后面的数进行比较,如果后面的数比它小则交换,i表示的是第几趟,第i趟无序区的第一个数为list【i】,从无序区第一个数开始和后面的数(list【i+1】)进行比较。

时间复杂度O(n2)

三:插入排序

原理:

(1)初始时手里(有序区)只有一张牌

(2)每次(从无序区)抽一张牌,根据比较插入到手里已有牌(有序区)的正确位置

def insert_sort(list):
    for i in range(1,len(list)):     #i指的是抽到的牌的下标
        temp = list[i]
        j = i-1        #j指的是手里的牌
        while j >= 0 and list[j] > temp:
            list[j+1] = list[j]
            j -= 1
        list[j+1] = temp
        print(list)

li = [6,5,9,3,4,8,2,7,1]
insert_sort(li)

假设列表首个元素是初始时手里有一张牌,这一张牌是有序区,每次抽一张牌,抽到最后一张牌,从list(1)抽到最后,所以一共抽了n-1次,且是从第二个元素开始,所以是for i in range(1,len(list)-1)。每次抽到的牌的下标为i,手里的牌是i的前一张牌也就是j=i-1。当抽到的牌比手里的牌小的时候,就将手里的牌往右移动一位,当抽到的牌大于手里的牌或者抽到的牌已经到最左边了,停止while循环,将抽到的牌放到手里的牌右边,以此类推 

时间复杂度O(n2)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值