选择排序实战案例
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.简单选择排序概述
简单选择排序 属于选择排序 两两比较大小,找出极值(极大值或极小值)被放置在固定的位置,这个固定位置一般指的是某一端 结果分为升序和降序排列 降序 n个数从左至右,索引从0开始到n-1,两两依次比较,记录大值索引,此轮所有数比较完毕,将大数和索引0数交换,如果大数就是索引1,不交换。第二轮,从1开始比较,找到最大值,将它和索引1位置交换,如果它就在索引1位置则不交换。依次类推,每次左边都会固定下一个大数。 升序 和降序相反 简单选择排序总结: 简单选择排序需要数据一轮轮比较,并在每一轮中发现极值 没有办法知道当前轮是否已经达到排序要求,但是可以知道极值是否在目标索引位置上 遍历次数1,...,n-1之和n(n-1)/2 时间复杂度O(n2) 减少了交换次数,提高了效率,性能略好于冒泡法
二.简单排序原理
初始值:[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]
三.使用Python代码实现简单排序
1>.简单选择排序代码实现
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 7 m_list = [ 8 [1,9,8,5,6,7,4,3,2], 9 [1,2,3,4,5,6,7,8,9], 10 [9,8,7,6,5,4,3,2,1] 11 ] 12 13 nums = m_list[1] 14 15 length = len(nums) 16 17 print(nums) 18 19 count_swap = 0 20 count_iter = 0 21 22 for i in range(length - 1): 23 maxindex = i #我们假设此轮的最大值的索引为i 24 25 for j in range(i+1,length): #注意我们循环的次数的起始位置,一旦排序号一个数字后,排序后的位置不应该再变动,因此这里的其实位置应该为"i+1" 26 count_iter += 1 27 if nums[maxindex] < nums[j]: #如果发现后面的索引比前面的大就需要修改最大索引 28 maxindex = j 29 30 if maxindex != i: #当最大索引再上面的哪个循环内发生改变时我们需要进行交换操作,否则就不需要进行交换 31 nums[maxindex],nums[i] = nums[i],nums[maxindex] 32 count_swap += 1 33 34 print(nums,count_swap,count_iter) 35 36 37 38 #以上代码输出结果如下: 39 [1, 2, 3, 4, 5, 6, 7, 8, 9] 40 [9, 8, 7, 6, 5, 4, 3, 2, 1] 4 36
2>.二元选择排序
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 """ 7 同时选择出每一趟的最大值和最小值,并分别固定到两端的有序区 8 减少迭代的躺数 9 """ 10 m_list = [ 11 [1,9,8,5,6,7,4,3,2], 12 [1,2,3,4,5,6,7,8,9], 13 [9,8,7,6,5,4,3,2,1] 14 ] 15 16 nums = m_list[1] 17 18 length = len(nums) 19 20 print(nums) 21 22 count_swap = 0 23 count_iter = 0 24 25 for i in range(length // 2): #依次固定2个数,因此循环的次数减半 26 maxindex = i 27 minindex = -i -1 #这里的最小值我们就选择列表最后面的数字索引 28 minorgin = minindex 29 30 for j in range(i+1,length -i): #每次右边也要减一个数 31 count_iter += 1 32 if nums[maxindex] < nums[j]: 33 maxindex = j 34 if nums[minindex] > nums[-j-1]: 35 minindex = -j -1 #负索引,即确定最小的索引,将最小的数放在最右边 36 37 if maxindex != i: 38 nums[maxindex],nums[i] = nums[i],nums[maxindex] 39 count_swap += 1 40 if i == minindex or i == length + minindex: #最小值位置被交换过 41 minindex = maxindex -length 42 43 if minindex != minorgin: #比较负索引 44 nums[minindex],nums[minorgin] = nums[minorgin],nums[minindex] 45 count_swap += 1 46 47 print(nums,count_swap,count_iter) 48 49 50 51 52 #以上代码执行结果如下: 53 [1, 2, 3, 4, 5, 6, 7, 8, 9] 54 [9, 8, 7, 6, 5, 4, 3, 2, 1] 4 20
3>.二元选择排序优化版本
1 #!/usr/bin/env python 2 #_*_conding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie 5 6 """ 7 同时选择出每一趟的最大值和最小值,并分别固定到两端的有序区 8 减少迭代的躺数 9 """ 10 m_list = [ 11 [1,1,1,1,1,1,1,1,2], 12 [1,2,3,4,5,6,7,8,9], 13 [9,8,7,6,5,4,3,2,1] 14 ] 15 16 nums = m_list[0] 17 18 length = len(nums) 19 20 print(nums) 21 22 count_swap = 0 23 count_iter = 0 24 25 for i in range(length // 2): #依次固定2个数,因此循环的次数减半 26 maxindex = i 27 minindex = -i -1 #这里的最小值我们就选择列表最后面的数字索引 28 minorgin = minindex 29 30 for j in range(i+1,length -i): #每次右边也要减一个数 31 count_iter += 1 32 if nums[maxindex] < nums[j]: 33 maxindex = j 34 if nums[minindex] > nums[-j-1]: 35 minindex = -j -1 #负索引,即确定最小的索引,将最小的数放在最右边 36 37 if nums[maxindex] == nums[minindex]: #说明剩余比较的数将全部相等,那么排序可以立即停止。 38 break 39 40 if maxindex != i: 41 nums[maxindex],nums[i] = nums[i],nums[maxindex] 42 count_swap += 1 43 if i == minindex or i == length + minindex: #最小值位置被交换过 44 minindex = maxindex -length 45 46 if minindex != minorgin and nums[minorgin] != nums[minindex]: #比较负索引,排除2个数字是一样的情况,这样交换是无意义的 47 nums[minindex],nums[minorgin] = nums[minorgin],nums[minindex] 48 count_swap += 1 49 50 print(nums,count_swap,count_iter) 51 52 53 54 55 #以上代码执行结果如下: 56 [1, 1, 1, 1, 1, 1, 1, 1, 2] 57 [2, 1, 1, 1, 1, 1, 1, 1, 1] 1 14