排序算法-选择排序-python

原创 2018年04月16日 20:26:26

1. 简单选择排序算法

  • 简单选择排序
    • 属于选择排序
    • 两两比较大小,找出极值(极大值或极小值)被放置在固定的位置,这个固定位置一般指的是某一端
    • 结果分为升序和降序排列
  • 降序
    • n个数从左至右,索引从0开始到n-1,两两依次比较,记录大值索引,此轮所有数比较完毕,将
      大数和索引0数交换,如果大数就是索引1,不交换。第二轮,从1开始比较,找到最大值,将它
      和索引1位置交换,如果它就在索引1位置则不交换。依次类推,每次左边都会固定下一个大数。
  • 升序
    • 和降序相反

2. 简单选择排序演示

初始 1 9 8 5 6 7 4 3 2
第一趟 9 1 8 5 6 7 4 3 2 选择出此轮最大值9,和索引0数交换
第二趟 9 8 1 5 6 7 4 3 2 选择出此轮最大值8,和索引1数交换
第三趟 9 8 7 5 6 1 4 3 2 以此类推
第四趟 9 8 7 6 5 1 4 3 2
第五趟 9 8 7 6 5 1 4 3 2
第六趟 9 8 7 6 5 4 1 3 2
第七趟 9 8 7 6 5 4 3 1 2
第八趟 9 8 7 6 5 4 3 2 1

3. 简单选择排序代码实现(一)*

m_list = [
    [1, 9, 8, 5, 6, 7, 4, 3, 2],
    [1, 2, 3, 4, 5, 6, 7, 8, 9],
    [9, 8, 7, 6, 5, 4, 3, 2, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 2]
]

nums = m_list[0]
length = len(nums)
print(nums)

count_swap = 0
count_iter = 0

for i in range(length):
    maxindex = i
    for j in range(i + 1, length):  # i-1个的列表内部找到最大值
        count_iter += 1
        if nums[maxindex] < nums[j]:
            maxindex = j  # 将最大值赋给maxindex

    if i != maxindex:
        nums[i], nums[maxindex] = nums[maxindex], nums[i]  # 最大值和索引i数交换
        count_swap += 1

print(nums, count_swap, count_iter)

4. 简单选择排序代码实现(二)

4.1. 优化实现

  • 二元选择排序
  • 同时固定左边最大值和右边最小值
  • 优点:减少迭代元素的次数
m_list = [
    [1, 9, 8, 5, 6, 7, 4, 3, 2],
    [1, 2, 3, 4, 5, 6, 7, 8, 9],
    [9, 8, 7, 6, 5, 4, 3, 2, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 2]
]

nums = m_list[0]
length = len(nums)
print(nums)

count_swap = 0
count_iter = 0
# 二元选择排序
for i in range(length // 2):
    maxindex = i
    minindex = -i -1
    minorigin = minindex
    for j in range(i +1, length - i):  # 每次左右都要少比较一个
        count_iter += 1
        if nums[maxindex] < nums[j]:
            maxindex = j
        if nums[minindex] > nums[-j -1]:
            minindex = -j -1
            # print(maxindex, minindex)
    if i != maxindex:
        nums[i], nums[maxindex] = nums[maxindex], nums[i]
        count_swap +=1
        # 如果最小值被交换过,要更新索引
        if i == minindex or i == length + minindex:
            minindex = maxindex
    if minorigin != minindex:
        nums[minorigin], nums[minindex] = nums[minindex], nums[minorigin]
        count_swap += 1
print(nums, count_swap, count_iter)
  • 代码解析:
    • 1、length//2 整除,通过几次运算就可以发现规律
    • 2、由于使用了负索引,所以条件中要增减 i == length + minindex
    • 还有没有优化的可能?

4.2. 改进实现

  • 如果一轮比较后,极大值,极小值的值相等,说明比较的序列元素全部相等
m_list = [
    [1, 9, 8, 5, 6, 7, 4, 3, 2],
    [1, 2, 3, 4, 5, 6, 7, 8, 9],
    [9, 8, 7, 6, 5, 4, 3, 2, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 2]
]

nums = m_list[3]
length = len(nums)
print(nums)

count_swap = 0
count_iter = 0
# 二元选择排序
for i in range(length // 2):
    maxindex = i
    minindex = -i -1
    minorigin = minindex
    for j in range(i +1, length - i):  # 每次左右都要少比较一个
        count_iter += 1
        if nums[maxindex] < nums[j]:
            maxindex = j
        if nums[minindex] > nums[-j -1]:
            minindex = -j -1
            # print(maxindex, minindex)
    if nums[maxindex] == nums[minindex]:  # 元素全相同
        break
    if i != maxindex:
        nums[i], nums[maxindex] = nums[maxindex], nums[i]
        count_swap +=1
        # 如果最小值被交换过,要更新索引
        if i == minindex or i == length + minindex:
            minindex = maxindex
    if minorigin != minindex:
        nums[minorigin], nums[minindex] = nums[minindex], nums[minorigin]
        count_swap += 1
print(nums, count_swap, count_iter)

4.3. 改进实现

  • [1, 1, 1, 1, 1, 1, 1, 1, 2]这种情况,找到的最小索引是-2, 最大值索引8, 上面的代码会交换2次,最小值两个1交换是无用功,所以,增加一个判断
m_list = [
    [1, 9, 8, 5, 6, 7, 4, 3, 2],
    [1, 2, 3, 4, 5, 6, 7, 8, 9],
    [9, 8, 7, 6, 5, 4, 3, 2, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 2]
]

nums = m_list[4]
length = len(nums)
print(nums)

count_swap = 0
count_iter = 0
# 二元选择排序
for i in range(length // 2):
    maxindex = i
    minindex = -i -1
    minorigin = minindex
    for j in range(i +1, length - i):  # 每次左右都要少比较一个
        count_iter += 1
        if nums[maxindex] < nums[j]:
            maxindex = j
        if nums[minindex] > nums[-j -1]:
            minindex = -j -1
            # print(maxindex, minindex)
    if nums[maxindex] == nums[minindex]:  # 元素全相同
        break
    if i != maxindex:
        nums[i], nums[maxindex] = nums[maxindex], nums[i]
        count_swap +=1
        # 如果最小值被交换过,要更新索引
        if i == minindex or i == length + minindex:
            minindex = maxindex
    if minorigin != minindex and nums[minorigin] != nums[minindex]:
        nums[minorigin], nums[minindex] = nums[minindex], nums[minorigin]
        count_swap += 1
print(nums, count_swap, count_iter)

5. 简单选择排序总结

  • 简单选择排序需要数据一轮轮比较,并在每一轮中发现极值
  • 没有办法知道当前轮是否已经达到排序要求,但是可以知道极值是否在目标索引位置上
  • 遍历次数1,…,n-1之和n(n-1)/2
  • 时间复杂度O(n2)
  • 减少了交换次数,提高了效率,性能略好于冒泡法

用Python实现八大排序算法--直接选择排序

一、选择排序概述选择排序(Selection sort)是一种简单直观的排序算法,它的工作原理是每次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,知道全部待排序的数据元素排完...
  • chibangyuxun
  • chibangyuxun
  • 2016-11-02 11:38:09
  • 1627

小白学数据结构——四、排序算法Python(冒泡、选择、快速、插入、希尔、归并排序)

排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。 我们通常所说的排序算法往往指的是内部排序算法,...
  • qq_33414271
  • qq_33414271
  • 2017-11-14 11:37:44
  • 5166

选择排序(伪代码算法,c++,以及python实现)

选择排序(伪代码算法,c++,以及python实现)
  • wxh928408225
  • wxh928408225
  • 2017-04-14 23:54:29
  • 239

IOS算法(二)之选择排序

经典的选择排序.
  • MHTios
  • MHTios
  • 2014-09-17 08:38:04
  • 2063

排序算法之选择排序的思想以及Java实现

1 基本思想 选择排序的思想是,每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。2,算法的实现(Java)package Algorit...
  • whq19890827
  • whq19890827
  • 2016-08-15 22:30:52
  • 2282

常见排序算法(二)(选择排序)

本文介绍排序算法中的选择排序,选择排序分为三种:直接选择排序、树形选择排序(锦标赛排序)、堆排序,并对每种排序算法进行了分析,附带java实现代码。...
  • sysukehan
  • sysukehan
  • 2016-09-25 14:01:41
  • 3007

“深入理解”—选择排序算法

选择排序算法有两种:直接选择排序和堆排序
  • qq_25827845
  • qq_25827845
  • 2016-07-10 11:37:25
  • 6983

排序算法Java实现——选择排序(直接选择排序)

基本思想:n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果 第一次比较:程序将记录定位在数组的第一个位置,拿第一个数据与后面的每个数据对比,用一个变量mix记录比第一个数小的数据的索...
  • singit
  • singit
  • 2017-04-22 22:30:12
  • 1836

排序算法之树形选择排序

树形选择排序又名锦标赛排序,算法思想与体育比赛类似, 首先将n个数据元素两两分组,分别按关键字进行比较,得到n/2个比较的优胜者(关键字小者),作为第一步比较的结果保留下来, 然后对这n/2个数据元素...
  • wf131410000
  • wf131410000
  • 2015-08-19 21:28:31
  • 2488

数据结构排序系列详解之六 树形选择排序

这篇博客接着来说说选择类排序之一的排序:树形选择排序 在简单选择排序中,每次的比较都没有用到上次比较的结果,所以比较操作的时间复杂度是O(N^2),想要降低比较的次数,则需要把比较过程中的大小关系保存...
  • S04103037
  • S04103037
  • 2013-07-30 11:39:25
  • 2417
收藏助手
不良信息举报
您举报文章:排序算法-选择排序-python
举报原因:
原因补充:

(最多只允许输入30个字)