上学期刚刚上完的数据结构,再问请教老师如何把它学好(老师许多地方都没有讲,如第8章,动态存储管理,当然B+树也没讲),决定暑假把它重新再看一遍。好了下面切入正题。
动态存储->可利用空间表示法

现在我们用着Java,c/C++,OC等等这些高级语言,一个变量,一个数据元素,我们只需简单的性质描述,就可以让它为我们的程序服务,而它到底存在那个存贮单元,它怎样存,我们不用关心,编译程序时编译与执行会自行分配这些。而早期的程序员,才是吊,这些都要完成!

动态存储它就是要解决:我们的系统如何应对用户/程序发出的存储“请求”;又如何收回那些不用的内存“释放”,给后面的”请求“做准备。

现在定义:可利用的空间快 = 空闲块,已分配的 = 占有块。

当然,最开始没有开始时,整个内存就是一个空闲块,也就是我们编译程序中说的“堆”!

请输入图片描述

而此时当你,用户,需要“请求”时,系统大致有两种做法:第1种.我觉得是简单粗暴型,它不管,继续把后面内存地址给你,当然,慢慢的,它给不了,因为已经到堆的底/顶了,这时它才会重新整合整个堆,把那些还是红的放在一起的节奏,然后给你的“请求”。
第2种,沉着合理型,它很科学,它努力让整个堆不出现浪费,它在你每次运行完,就开始检查,整个内存,如果它给不了你的“请求”,那就真满了!

沉着合理型,空能决定了它的不简单,所以,为了能完成每次一个任务完成整和内存,它有个记录空闲块的东西,可以是表,当然链表也可以。表大多用在操作系统,不过现在还没学。

请输入图片描述

上图一个简单的表示空闲快的链表雏形,当你用时,在合适的位置删除一个节点,当你回收时,在合适的位置加一个节点

链表还有三种动态存储方法

1:最简单的,每个节点大小是死的,只有那么大,没有差异,所以无论“请求”,“释放”,只需在头节点改就可以,就像先进后出的栈。

2:稍稍复杂,有几个节点大小一致的组合,就像若干个大小第一种
组合一下,在”请求“时,先找和自己差不多大的链表找(这就和第一种一样),如果没有再去,比此链表大的找,并只去走所需的,剩下的和链表们比较,放在合适的链表里。

3:系统在运行期间分配给用户的内存快事大小不固定的,可以随请求改变,因此,可利用空间表的节点既空闲快的大小也是随意的,通常操作系统中的可利用表就是这种。

系统刚开始时,整个内存就是一个空闲块,既可利用的空闲表只有一个大小为整个内存的区的节点,随着系统运行,节点的大小与个数都发生了变化。

由于表中节点的大小不一样,分配就会出现问题,如,你需要n,节点为m(m>=n),所以剩m-n;可试想有很多个不小于n的空闲块,那如何分?

(1)首次拟合法。这个也属于简单粗暴型,它从头节点开始比较,只要出现不小于n的就给,所以此链表本身没有顺序(大小,地址)。

(2)最佳拟合法。最合理,但也较复杂与费时,它的空闲块的链表按大小从小到大,遍历链表,出现比n大的就给,回收时占有快时,因为链表是节点大小有序的,所以得插在合适位置。

(3)最差拟合法,其实就是首次拟合的倒序,一个在找时遍历,一个在回收插时遍历,最差拟合,链表从大到小,只是为了,在“请求”时,只用判断头节点>n?,而在回收时就得放在合适的位置。

一般来说,(2)最佳拟合法,更适合请求分配的内存大小范围广的。(3)最差拟合适合范围窄的。(1)首次拟合适合事先不掌握运行期间可能出现的请求分配与释放的信息情况。


酷行僧
13 声望0 粉丝