选择排序算法(Selection Sort)是排序算法的一种初级算法。虽然比较简单,但是基础,理解了有助于后面学习更高深算法,勿以勿小而不为。

排序算法的语言描述:

给定一组物体,根据他们的某种可量化的属性,进行从大到小或从小到大排序。

比如,上体育课的时候,同学们按照身高排队。

排序看起来是一个简单的问题,但针对它的计算机算法有很多,性能各不一样。本文的选择算法即是其中一种。

选择排序算法的语言描述:

选择排序算法是,从一组未排序的物体中,根据某可量化的属性,先选出最小或最大的一个,放到第一个位置;然后再从剩下的物体中,选出最小(或最大)的,放到第二个位置,以此类推直到全部排完。

这里的重点是,存在两个选择问题,一个是每次要选出一个极值,另一个是选择极值是最大还是最小,所以叫选择排序算法,这是我为了便于记住这个算法名及其逻辑,这么理解的。

以同学们按身高排队为例:第一次,所有同学中最矮的那个拎出来,跟第一个同学换一下位置,这样第一个位置上的同学就是最矮的了,保持不动。接下来,比较第二个同学与他后面的同学挨个比较,找出最矮的和第二个同学换下位置,如果第二个同学是最矮的就保持不动。以此类推。

选择排序算法的计算机语言描述

从一个 N 个数的数组或列表中,按从大到小或从小到大排序,排序的方法是:

1 确定是按从大到小还是从小到大排。(这里我们选择从小到大排序)

2 从小到大排的话,数组的第一个值最后存放的是最小的值,最后一个值存放最大值

3 确定是从第一个值还是最后一个值开始。从第一个值开始的话,每次找出最小值,从前往后更新数组。从最后一个值开始的话,每次找出最大值,从后往前更新数组。(下文的算法实现选择的是后者)

4 假设我们每次找最大值,从后往前更新数组。第一轮将最后一个值与其他所有值挨个比较,将最大的那个与最后一个值相交换。如果最后一个值就是最大值,则无需作。这样,数组的最后一个值现在存放的就是整个数组的最大值了。

5 第二轮将倒数第二个值与它前面的所有值挨个比较,找出最大值与倒数第二个值交换。

6 以此类推,直到第二个和第一个值比较。

选择排序算法的实现

这里用的是Python,(Java 实现请参考Selection.java)

选择的是每次寻找最大值,从后往前排。和经典选择排序算法有点不太一样(最小值法),是为了给自己增加点难度避免直接看答案。

算法实现代码(selection_sort.py):

  1. # -*- coding: utf-8 -*-
  2. class SelectionSort(object):
  3. items=[]
  4. def __init__(self,items):
  5. self.items = items
  6. def sort(self):
  7. print "iten len: %d" % len(self.items)
  8. for i in range(len(self.items)-1,0,-1):
  9. maximum = i
  10. for j in range(0,i):
  11. if (self.items[i] < self.items[j]):
  12. maximum = j
  13. self.items[i],self.items[maximum]=self.swap(self.items[i],self.items[maximum])
  14. def swap(self,i,j):
  15. temp = j
  16. j = i
  17. i = temp
  18. return i,j

测试代码:

  1. # -*- coding: utf-8 -*-
  2. import random
  3. import string
  4. from timeit import default_timer as timer
  5. from selection_sort import SelectionSort
  6. print "-"*10 + "sorting numbers" + "_"*10
  7. items = []
  8. # generate random numbers and put in items
  9. for i in range(0,10):
  10. items.append(random.randint(2,999))
  11. print "original items: %r" % items
  12. ssort = SelectionSort(items)
  13. # calculate execution time for our selection sort method
  14. start = timer()
  15. ssort.sort()
  16. end = timer()
  17. duration1 = end - start
  18. # calculate execution time for python built-in sort method
  19. start = timer()
  20. items.sort()
  21. end = timer()
  22. duration2 = end - start
  23. assert ssort.items == items
  24. print "sorted items: %r" % ssort.items
  25. print "Duration: our selection sort method - %ds, python builtin sort - %ds" % (duration1, duration2)

测试代码中,我们还用了python自带的sort方法,通过 "assert ssort.items == items" 一行语句是来验证我们的选择排序算法运行结果的正确性。并且加了timer,来比较我们的算法和python自带的sort方法的运行时间。

运行结果表明,排序的结果是一样的,但我们的算法在数组很大的时候,比如数组size 在4000左右,需要耗时1s多,而python自带的算法超快,毫秒级。当数据到10,000时我们的算法要运行5s多,但python自带的sort方法仍然不到1s。这说明选择排序算法简单,但是性能并不佳。

运行结果示例(数组size=10):

  1. ----------sorting numbers__________
  2. original items: [434, 706, 256, 95, 549, 380, 585, 535, 722, 689]
  3. iten len: 10
  4. sorted items: [95, 256, 380, 434, 535, 549, 585, 689, 706, 722]
  5. Duration: our selection sort method - 0s, python builtin sort - 0s

关于字符串排序,也一并放上来测试代码和运行结果:

  1. # -*- coding: utf-8 -*-
  2. import random
  3. import string
  4. from timeit import default_timer as timer
  5. from selection_sort import SelectionSort
  6. print "-"*10 + "sorting alpha characters" + "_"*10
  7. items=[]
  8. for i in range(0,10):
  9. items.append(random.choice(string.ascii_letters))
  10. print "original items: %r" % items
  11. ssort = SelectionSort(items)
  12. ssort.sort()
  13. items.sort()
  14. assert ssort.items == items
  15. print "sorted items: %r" % ssort.items
  16. print "-"*10 + "sorting strings" + "_"*10
  17. items=[]
  18. for i in range(0,10):
  19. items.append("".join(random.choice(string.ascii_letters+string.digits) for s in range(0,10) ))
  20. print "original items: %r" % items
  21. ssort = SelectionSort(items)
  22. ssort.sort()
  23. items.sort()
  24. assert ssort.items == items
  25. print "sorted items: %r" % ssort.items

运行代码:


  1. ----------sorting alpha characters__________
  2. original items: ['m', 'q', 'a', 'c', 'n', 'w', 'V', 'f', 'a', 'p']
  3. iten len: 10
  4. sorted items: ['V', 'a', 'a', 'c', 'f', 'm', 'n', 'p', 'q', 'w']
  5. ----------sorting strings__________
  6. original items: ['QSvTmfkUAX', 'uf2dEtEtlk', 'lzyYWD3w59', '3pCKM10RPK', 'ARDf403rrl', 'dZyirpxn2N', 'picoZ7yvhR', 'VU9aW1PSbt', 'YvwqwzO39r', 'ROxlks3zAl']
  7. iten len: 10
  8. sorted items: ['3pCKM10RPK', 'ARDf403rrl', 'QSvTmfkUAX', 'ROxlks3zAl', 'VU9aW1PSbt', 'YvwqwzO39r', 'dZyirpxn2N', 'lzyYWD3w59', 'picoZ7yvhR', 'uf2dEtEtlk']

选择排序算法分析

通过前面算法实现的例子,选择排序算法是有性能问题的。

我们试着通过在算法中用到的比较次数和值交换次数来分析一下:

找第一个最大值时,需要比较 N-1次,交换1次

找第二个最大值时,需要比较 N-2次,交换1次

找最后一个值时,需要比较1次,交换1次

所以,一共交换 1+2+...+(N-1) 次 = (N的平方)/2次,其复杂度已经不是线性的了。总交换次数是N次,相对还好点。

思考一下,如果要改进选择排序算法,有什么办法?

《算法4》2.1 - 选择排序算法(Selection Sort), Python实现的更多相关文章

  1. 排序算法(sorting algorithm) 之 选择排序(selection sort)

    https://en.wikipedia.org/wiki/Selection_sort loop1: 4,6,1,3,7 -> 4,6,1,3,7 4,6,1,3,7 -> ,3,7 1 ...

  2. js 实现排序算法 -- 选择排序(Selection Sort)

    原文: 十大经典排序算法(动图演示) 选择排序(Selection Sort) 选择排序(Selection-sort)是一种简单直观的排序算法.它的工作原理:首先在未排序序列中找到最小(大)元素,存 ...

  3. 【算法】选择排序(Selection Sort)(二)

    选择排序(Selection Sort) 选择排序(Selection-sort)是一种简单直观的排序算法.它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余 ...

  4. 数据结构 - 树形选择排序 (tree selection sort) 具体解释 及 代码(C++)

    树形选择排序 (tree selection sort) 具体解释 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 算法逻辑: 依据节点的大小, ...

  5. 【排序基础】1、选择排序法 - Selection Sort

    文章目录 选择排序法 - Selection Sort 为什么要学习O(n^2)的排序算法? 选择排序算法思想 操作:选择排序代码实现 选择排序法 - Selection Sort 简单记录-bobo ...

  6. 简单选择排序(Simple Selection Sort)

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  7. 数据结构 - 只需选择排序(simple selection sort) 详细说明 和 代码(C++)

    数据结构 - 只需选择排序(simple selection sort) 本文地址: http://blog.csdn.net/caroline_wendy/article/details/28601 ...

  8. 选择排序(Selection Sort)

    选择排序就是在选择数组元素上做文章,关键是如何选择?选择的标准是什么?选择之后放在哪?所有这些都是选择排序的问题. 选择排序算法中,通常会有以下操作: 从数组第一个元素开始. 遍历整个数组,找到最小的 ...

  9. 【DS】排序算法之选择排序(Selection Sort)

    一.算法思想 选择排序是一种简单直观的排序算法.它的工作原理如下: 1)将序列分成两部分,前半部分是已经排序的序列,后半部分是未排序的序列: 2)在未排序序列中找到最小(大)元素,放到已排序序列的末尾 ...

  10. 算法:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)和选择排序(Selection Sort)总结

    背景 这两天温习了 5 中排序算法,之前也都看过它们的实现,因为没有深入分析的缘故,一直记不住谁是谁,本文就记录一下我学习的一些心得. 三种排序算法可以总结为如下: 都将数组分为已排序部分和未排序部分 ...

随机推荐

  1. Windows入门基础:2.vs2013中Icon显示

    第一:系统小图标的显示 wndclass.hIcon = LoadIcon(NULL,IDI_WARNING); //LoadIcon函数的第一的参数要为0,第二个参数是系统自定义的ID号: IDI_ ...

  2. VS窗体选择BackGroupImage属性报错:已添加具有相同键的项

    高墙我今天第一次遇见这个问题.既然说是"已添加具有相同键的项."那我自然地认为会不会是文件夹哪里命名了两个相同的文件名.然后在这个Exception上越走越远. 好了不说废话.出现 ...

  3. C++命名空间【转】

    本讲基本要求 * 掌握:命名空间的作用及定义:如何使用命名空间.     * 了解:使用早期的函数库 重点.难点     ◆命名空间的作用及定义:如何使用命名空间.     在学习本书前面各章时,读者 ...

  4. linux常用操作命令

    cd: cd /data 进入目录 cd .. 返回上级菜单tar: tar -cvf jcms20170411.tar.gz jcms/ 将jcms文件夹打包为 jcms20170411.tar.g ...

  5. 事件驱动的简明讲解(python实现)

    关键词:编程范式,事件驱动,回调函数,观察者模式 作者:码匠信龙 举个简单的例子: 有些人喜欢的某个公众号,然后去关注这个公众号,哪天这个公众号发布了篇新的文章,没多久订阅者就会在微信里收到这个公众号 ...

  6. 事件的preventDefault方法

    事件有一个preventDefault()方法,该方法可以用来取消事件的默认行为.许多事件都有默认执行的关联行为.例如,如果用户在文本字段中键入一个字符,则默认行为就是在文本字段中显示该字符.由于可以 ...

  7. css3---线性渐变

    .example1 { width: 150px; height: 80px; background: -moz-linear-gradient( top,#ccc,#000); background ...

  8. 学习《ASP.NET MVC5高级编程》——基架

    基架--代码生成的模板.我姑且这么去定义它,在我学习微软向编程之前从未听说过,比如php代码,大部分情况下是我用vim去手写而成,重复使用的代码需要复制粘贴,即使后来我在使用eclipse这样的IDE ...

  9. PHP学习笔记-4(时间戳)

    在学习PHP时间戳的时候,发现了一个有趣的现象,就是发现用strtotime()这个函数返回的时间戳跟人家的不一样,以为是自己哪里写错了,后来发现不是这样的. 是因为设置的时区不同,从而导致了时间显示 ...

  10. 详解MySQL存储过程的“异常处理”

    阅读目录:存储过程的异常处理 定义异常处理 单一异常处理程序 continue exit 多个异常处理程序 关于错误编号和SQLSTATE码 使用3个处理程序 忽略某一异常的处理 异常处理的命名 异常 ...