数据结构(python)——【06排序: 选择排序】

数据结构——选择排序

    选择排序与前面介绍的冒泡排序要简单一点,不管是思路还是代码。

1. 思路:

    将整个列表分为两个区域: 有序区和无序区,每次找出无序区中的最小值,放在有序区,直到无序区里没有值。
    具体算法思想放在下面的算法讲解再仔细介绍。

2. 代码
1. 法一:

具体思路:
    这一算法的思路非常简单,我们开出了一个新的列表用于储存每次选出的无序区的最小值,作为有序区。每次选出无序区的最小值后,就把无序区的这个最小值移除掉,可以保证每次选的都是无序区的最小值,且该最小值大于有序区目前的最大值!

def select_sort(li):
    li_new = []
    for i in range(len(li)):
        min_val = min(li)
        li_new.append(min_val)
        li.remove(min_val)
        print("第%d趟排序后的无序区:" % i)
        print(li)
        print("第%d趟排序后的有序区:" % i)
        print(li_new)
    return li_new
li = [3, 4, 2, 1, 5, 7, 9, 6, 8]
print(li)
select_sort(li)

结果为:

[3, 4, 2, 1, 5, 7, 9, 6, 8]0趟排序后的无序区:
[3, 4, 2, 5, 7, 9, 6, 8]0趟排序后的有序区:
[1]1趟排序后的无序区:
[3, 4, 5, 7, 9, 6, 8]1趟排序后的有序区:
[1, 2]2趟排序后的无序区:
[4, 5, 7, 9, 6, 8]2趟排序后的有序区:
[1, 2, 3]3趟排序后的无序区:
[5, 7, 9, 6, 8]3趟排序后的有序区:
[1, 2, 3, 4]4趟排序后的无序区:
[7, 9, 6, 8]4趟排序后的有序区:
[1, 2, 3, 4, 5]5趟排序后的无序区:
[7, 9, 8]5趟排序后的有序区:
[1, 2, 3, 4, 5, 6]6趟排序后的无序区:
[9, 8]6趟排序后的有序区:
[1, 2, 3, 4, 5, 6, 7]7趟排序后的无序区:
[9]7趟排序后的有序区:
[1, 2, 3, 4, 5, 6, 7, 8]8趟排序后的无序区:
[]8趟排序后的有序区:
[1, 2, 3, 4, 5, 6, 7, 8, 9]

算法复杂度:
    min函数和remove的时间复杂度都是 O ( n ) O(n) O(n),而这两个函数又是放在一个遍历的下面,所以时间复杂度 O ( n 2 ) O(n^2) O(n2)

2. 法二:

具体思路:
    不开新列表,直接在原列表中进行操作,将原列表分为有序区和无序区两个区域。刚开始整个列表都是无序区,然后选取第一个值为最小值,并取得该值的索引,然后遍历第一个值后面的值,选出后面的值的最小值,再交换第一个值和后面选出的最小值的位置,依次下去。
简单来说:

  1. 第0趟排序记录最小的数,放到第一个位置
  2. 第1趟排序,记录列表无序区最小的数,放到第二个位置
  3. 第2趟排序,记录列表无序区最小的数,放到第三个位置
def select_sort(li):
    for i in range(len(li) - 1):    # 只需要n-1趟, i是第几趟
        min_location = i
        for j in range(i+1, len(li)):
            if li[j] < li[min_location]:
                min_location = j
        li[i], li[min_location] = li[min_location], li[i]
        print("第%d趟排序后的列表: " % i)
        print(li)
li = [3, 4, 2, 1, 5, 7, 9, 6, 8]
print(li)
select_sort(li)

结果为:

[3, 4, 2, 1, 5, 7, 9, 6, 8]0趟排序后的列表: 
[1, 4, 2, 3, 5, 7, 9, 6, 8]1趟排序后的列表: 
[1, 2, 4, 3, 5, 7, 9, 6, 8]2趟排序后的列表: 
[1, 2, 3, 4, 5, 7, 9, 6, 8]3趟排序后的列表: 
[1, 2, 3, 4, 5, 7, 9, 6, 8]4趟排序后的列表: 
[1, 2, 3, 4, 5, 7, 9, 6, 8]5趟排序后的列表: 
[1, 2, 3, 4, 5, 6, 9, 7, 8]6趟排序后的列表: 
[1, 2, 3, 4, 5, 6, 7, 9, 8]7趟排序后的列表: 
[1, 2, 3, 4, 5, 6, 7, 8, 9]

第0趟排序:
先选索引值为0的3作为最小值,在3后面的值中进行比较,选出后面值中的最小值,再做交换,结果为3和1进行交换,所以此时有序区为1,并且1在列表第一个位置。
第1趟排序:
选索引值为1的4作为最小值(这样子也可以避免选择到有序区的值,现在有序区只有一个值,放在最前面,所以索引为1的时候刚好从有序区后面开始),在4后面的值中进行比较,再做交换,结果为4和2进行交换,所以此时有序区为[1, 2],并且2在列表第二个位置。
. . . . . . . . . . . ........... ...........
算法复杂度:
    时间复杂度为 O ( n 2 ) O(n^2) O(n2)

3. 总结:

    上述介绍了两种不同方法,两种方法的时间复杂度均为 O ( n 2 ) O(n^2) O(n2),但是法一的空间复杂度比法二复杂,因为法一要重开一个列表,所以这里比较推荐法二。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值