【第二天】算法图解 之 选择排序

简介: 【第二天】算法图解 之 选择排序

1. 内存的工作原理


计算机内存的工作原理,就像是很多抽屉的集合体,每个抽屉都有地址


需要将数据存储到内存时,你请求计算机提供存储空间,计算机给你一个存储地址


需要存储多次数据时,有两种基本方式——数组和链表


2. 数组和链表


使用数组意味着所有待办事项在内存中都是相连的


①链表


链表中的元素可存储在内存的任何地方


链表的每个元素都存储了下一个元素的地址,从而使一系列随机的内存地址串在一起。只要有足够的内存空间,就能为链表分配内存


链表的优势在插入元素方面


② 数组


* 排行榜网站使用卑鄙的手段增加页面浏览量。他们不在一个页面中显示整个排行榜,而将排行榜的每项内容都放在一个页面中,并让你单击Next来查看下一项


链表存在类似的问题。在需要读取链表的最后一个元素时,你不能直接读取,因为你不知道它所处的地址,必须先访问元素#1,从中获取元素#2的地址,再访问元素#2获取元素#3的地址,以此类推,直到访问最后一个元素。


需要读取所有元素时,链表的效率很高,但如果你需要跳跃,链表的效率真的很低


数组与此不同:你知道每个元素的地址


随机的读取元素时,数组的效率很高,因为可迅速找到数组的任何元素。在链表中,元素并非靠在一起的,你无法迅速计算出第五个元素的内存地址,而必须先访问第一个元素以获取第二个元素的地址,再访问第二个元素以获取第三个元素的地址,以此类推,直到访问到第五个元素。


③术语


数组的元素带编号,编号从0而不是从1开始


元素的位置称为索引


④在中间插入


要让待办事项按日期排序,现在要根据新增的待办事项的日期将其插入到正确的位置

1> 使用链表时,插入元素很简单,只需修改它前面的那个元素指向的地址


2> 使用数组时,则必须将后面的元素都向后移。如果没有足够的空间,可能还得将整个数组复制到其他地方!因此,当需要在中间插入元素时,链表是更好的选择


⑤ 删除


删除元素时,链表也是更好的选择,因为只需修改前一个元素指向的地址即可。而数组删除元素后,后面的元素都会向前移


如果内存中没有足够的空间,插入操作可能失败,但在任何情况下都能够将元素删除

常见数组和链表操作的运行时间


数组 链表

读取

O(1) O(n)
插入 O(n) O(1)
删除 O(n) O(1)


仅当能够立即访问要删除的元素时,删除操作的运行时间才为O(1),链表中我们都记录了第一个元素和最后一个元素,删除这些元素时运行时间也为O(1)


数组:支持随机访问(用的很多)


链表:只能顺序访问(第一个元素开始逐个的读取元素)


扩展:链表数组


这个数组包含26个元素,每个元素都指向一个链表



3. 选择排序


假如你的计算机存储了许多乐曲,记录了每个乐队的作品被播放的次数,要将列表按播放次数从多到少的顺序排序,该如何做?


一种方法便是:遍历这个列表,找出播放次数最多的乐队,并将该乐队添加到一个新列表中,再次这样做,找出第二多的乐队,继续这样做,将得到一个有序列表,则需要的总时间为O(n*n),即O(n^2)


需要检查的元素越来越少


随着排序的进行,每次需要检查的元素数在逐渐减少,最后一次需要检查的元素都只有一个。既然如此,运行时间为什么还是O(n^2)?


第一次需要检查n个元素,但随后检查的元素数依次为 n-1,n-2,……,2,1.平均每次检查的元素数为(1/2)*n,则运行时间为O(n*(1/2)*n),但大O表示法省略诸如(1/2)这样的常数,因为写为O(n*n或O(n^2)


* 排序算法是一种灵巧的算法,但其速度不是很快,快速排序是一种更快的排序算法,其运行时间为O(nlogn)


4. 代码示例


def findSmallest(arr):
    smallest = arr[0]
    smallest_index = 0
    for i in range(1, len(arr)):
        if arr[i] < smallest:
            smallest = arr[i]
            smallest_index = i
    return smallest_index
def selectionSort(arr):
    newArr = []
    for i in range(len(arr)):
        smallest = findSmallest(arr)
        newArr.append(arr.pop(smallest))
    return newArr


测试:


print(selectionSort([5, 3, 6, 2, 10]))


运行结果


[2, 3, 5, 6, 10]


5. 小结


①计算机内存犹如一大堆抽屉


②需要存储多个元素时,可使用数组和链表


③数组的元素都在一起


④数组的读取速度很快


⑤链表的元素是分开的,其中每个元素都存储下一个元素的地址


⑥链表的插入和删除速度很快


⑦在同一个数组中,所有元素的类型都必须相同(都为int、double)

相关文章
|
1月前
|
算法 搜索推荐
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
本文介绍了冒泡排序、选择排序和插入排序三种基础排序算法的原理、实现代码和测试结果。
17 0
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
|
1月前
|
搜索推荐 Java Go
深入了解选择排序算法
深入了解选择排序算法
22 4
|
1月前
|
搜索推荐 算法
【排序算法(一)】——插入排序,选择排序 —> 深层解析
【排序算法(一)】——插入排序,选择排序 —> 深层解析
|
1月前
|
算法 Python
Python算法编程:冒泡排序、选择排序、快速排序
Python算法编程:冒泡排序、选择排序、快速排序
|
3月前
|
搜索推荐 算法 Java
经典排序算法之-----选择排序(Java实现)
这篇文章通过Java代码示例详细解释了选择排序算法的实现过程,包括算法的基本思想、核心代码、辅助函数以及测试结果,展示了如何通过选择排序对数组进行升序排列。
经典排序算法之-----选择排序(Java实现)
|
5月前
|
机器学习/深度学习 算法 搜索推荐
数据结构算法--2 冒泡排序,选择排序,插入排序
**基础排序算法包括冒泡排序、选择排序和插入排序。冒泡排序通过相邻元素比较交换,逐步将最大值“冒”到末尾,平均时间复杂度为O(n^2)。选择排序每次找到剩余部分的最小值与未排序部分的第一个元素交换,同样具有O(n^2)的时间复杂度。插入排序则类似玩牌,将新元素插入到已排序部分的正确位置,也是O(n^2)复杂度。这些算法适用于小规模或部分有序的数据。**
|
5月前
|
搜索推荐
排序算法---选择排序-----详解&&代码
排序算法---选择排序-----详解&&代码
|
5月前
|
算法 搜索推荐
数据结构与算法-选择排序
数据结构与算法-选择排序
31 4
|
5月前
|
搜索推荐 算法
【C/排序算法】:堆排序和选择排序
【C/排序算法】:堆排序和选择排序
34 0
|
5月前
|
算法 搜索推荐 Java
JavaSE——算法(1/2):认识、冒泡排序、选择排序及优化(介绍、详细图解、代码)
JavaSE——算法(1/2):认识、冒泡排序、选择排序及优化(介绍、详细图解、代码)
36 0
下一篇
无影云桌面