文章目录
1.本章内容
-
学习两种最基本的数据结构——数组和链表。
需要明确——
– 数组是很重要的主题
– 有些情况下使用链表比使用数组更加合适 -
阐述数组和链表的优缺点,要学会根据要实现的算法选择合适的一个——数组 or 链表。
-
学习选择排序并进行代码的实现,很多算法仅在数据经过排序后才管用。
–第一章的二分查找——只能用于有序元素列表
–本章介绍选择排序——许多语言内置了排序算法,所以不用从头开始编写自己的版本。 -
选择排序是下一章将要介绍的快速排序的基石。
–快排是一种非常重要的算法!
2.内存的工作原理
我们可以在抽屉里存东西~
计算机就像是很多类似抽屉的集合体,每个抽屉都有地址。
需要将数据存储到内存时,你请求计算机提供存储空间,计算机给你一个存储地址。需要存储多项数据时,有两种基本方式——数组和链表。
但它们并非都适用于所有的情形,因此知道它们的差别很重要。接下来介绍数组和链表以及它们的优缺点。
3.数组和链表
想象一个场景~
我们需要在内存中存储一系列元素,例如:编写一个管理待办事项的应用程序时,需要将待办事项存储在内存中
所以——用数组还是链表呢?
首先 数组的概念更加简单,但是!——
使用了数组 所有待办事项在内存中都是相连的,这会造成——
添加新的待办事项时,可能没有空余的内存了!
例如有4个待办事项要放在一起 但是只有三个位置了!所以还得转移这4个待办事项…
预留座位(例如:请计算机提供10个空余位置,以防添加待办事项)可以解决这个问题 但是有点越描越黑的感觉…:
- 额外请求的位置可能用不上 浪费内存!
- 待办事项超过10个 还得转移这些元素!
所以——数组再见 咱们来看看链表~
3.1 链表
链表中的元素可以存储在内存的任何地方
链表的每个元素都存储了下一个元素的地址,从而使一系列随机的内存地址串在一起。
插入元素的时候,链表优势很大哦~
那么数组有啥优势呢?
3.2 数组
链表也存在类似的问题,读取链表的最后一个元素时,不可以直接读取,因为我们不知道这个元素所处的地址(第n个元素的地址存在第n-1个元素之中)!必须先访问元素#1 再访问#2 最后访问到#n。
读取所有元素时 链表效率很高
但是只要读其中几个元素时 效率贼低诶。
数组与此不同。
我们知道其中每个元素的地址。
需要随机读取元素的时候 数组效率很高。
3.3 数组和链表操作的运行时间
数组读取更方便
链表插入更方便
链表删除更方便
3.4 在之间插入元素
需要在中间插入元素时 链表好使!
-
链表
想在索引为2的地方插入元素?
简单!修改索引为1的元素指向的地址不就得了~ -
数组
在索引为2的地方插入元素?
麻烦了 从索引=3的元素开始全往后挪…如果没有足够的空间 还得把这一坨元素复制到其他地方 。
3.5 删除
要删除元素?
链表更好!
和插入同理
3.6 数组 or 链表 用谁?
需要看情况嗷~
数组用得相对较多,因为数组支持随机访问!
链表使用顺序访问 读取速度会慢~
在实际应用中,好多情况要求能够随机访问,所以数组用得较多一些。
当然 数组和链表还被用来实现其他数据结构。
4.选择排序
4.1 举个栗子来引入
计算机存储了很多乐曲 对于每个乐队都记录了其作品被播放的次数:
我们要将这个列表按播放次数从多到少地顺序排列
遍历列表找出播放数最多的乐队 并且将该乐队添加到一个新列表里
接下来 继续找出第二多的
以此类推 得到有序序列
但是这个方法需要进行n次简单查找!
每次复杂度为O(n) 要执行n次这个操作
需要的总时间为O(nxn) 即O(n^2)
可见 选择排序虽然是一种灵巧的算法 但是它的速度不是很快。
下章来说说快排 运行时间为O(n*log n)
虽说并非每次都检查n个元素 但是——
大O表示法 省略常数!
4.2 选择排序代码!
选择排序代码(对数组进行操作):
先写一个 找出数组中最小元素的函数
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中
newArr.append(arr.pop(smallest))
return newArr
最后进行测试~ perfect
5.小结
- 计算机内存犹如一大堆抽屉 我们可以在里面存东西
- 需要存储多个元素时,可以使用数组或者链表
- 数组的元素都紧挨着存在一起
- 链表的元素是分开的 每个元素都存储了下一个元素的地址
- 数组的 读取速度 很快!
- 链表的 插入、删除速度 很快
- 在同一个数组中 所有元素的类型都必须相同(都为int double等)