现在考虑到我们需要将数据存储在链接列表中(因为链接列表中的节点数量将等于存储的实际数据项,也就是说,没有额外的空间,例如一个数组),但是我们不允许使用对于每个节点,一次又一次地堆积地面。对于某些人来说,这可能看起来像是一种假设的情况,但这在嵌入式系统中并不是很少的要求。从基本上讲,在几个嵌入式程序中,由于各种原因,这是不允许通过malloc()分配内存。
一个明显的原因是,在Malloc()分布的时间复杂性方面的性能非常高,因为在大多数情况下需要确定嵌入式程序。其他原因可能是模块特定的内存管理嵌入式系统中的模块可以管理自己的内存。
简而言之,如果我们需要执行自己的内存管理,我们可以选择系统模拟的链接列表,而无需依赖于系统提供的malloc()和free()API。我希望您知道为什么我们可能需要使用一个数组以模拟链接列表。
如果我们初始化此链接列表(实际上是一个数组),则将在下面显示在内存中:
要注意的重要点是,链接列表的所有节点在内存中连续(每个节点占8个字节),并且每个节点的nextExex设置为-1。到目前为止,链接列表的节点是空的。此链接列表由Head Index 0表示。
现在,如果此链接列表不断使用数据部分4、3、2和1的四个元素进行更新,则将在下面显示在内存中。此链接列表可以被认为为0x500-> 0x508-> 0x510-> 0x518-> 0x518。
要注意的重要点是,下一个节点(即,第四个节点)设置为-2.(即-2)是为了表达链接列表的结尾。加法,链接的头节点。列表为索引0。如果我们从上面的链接列表中删除第二个节点,则使用数组仿真链接列表的概念看起来更有趣。在这种情况下,链接列表将如下显示在内存中:
结果链接列表为0x500-> 0x510-> 0x518。现在,第一个节点指向第三个节点(索引2)。
我希望以上示例可以给出一些想法。对于模拟链接列表,我们需要编写自己的API,类似于Malloc()和Free(),这些API基本上用于插入和删除节点。用算法完成。
有很多方法可以做到这一点。如果我们使用一种简单的方法来创建链接列表,我们可以使用以下逻辑。用于插入节点,穿越底部阵列并找到NextIndex的节点到-1。这意味着此节点是空的。将此节点用作新节点。填写此新节点的数据部分,并将此节点的nextExe设置为链接列表的当前head节点(即,head索引)。节点用作链接列表的头部索引。
对于图像,让我们给我们一个示例。修复链接列表如下,头部索引为0,链接列表为0x500-> 0x508-> 0x518-> 0x520
插入具有8个新节点后,链接列表将如下显示,头部索引为2。
因此,链接列表节点将位于地址0x510-> 0x500-> 0x508-> 0x518-> 0x520
对于删除节点,我们需要将节点的NextExex设置为-1,以将节点标记为一个空节点。要删除。我们可以看到,我们已经完成了自己的内存管理以从数组内存创建链接列表。在时间复杂性方面找到一个空节点是如此有效。基本上,我们正在线性搜索中搜索一个数组以找到一个空节点。
让我们看看是否可以进一步优化它。基本地,我们还可以维护同一数组中的空节点的链接列表。在这种情况下,链接列表将由两个索引 - A链接列表表示,带有实际数据值,是,到目前为止插入的节点以及空节点的链接列表的其他索引。通过这样做,每当我们需要在现有链接列表中插入一个新节点时,我们都可以快速找到一个空Node.let。举一个例子:
上面有两个索引(0和5)表达的两个链接列表:一个用于实际值,另一个用于空节点。带有实际值的链接列表在地址0x500-> 0x510-> 0x528,带有空节点的链接列表在地址0x520-> 0x508-> 0x518带有节点。可以看到,找到空节点应该更快(即类似于malloc()),因为我们可以快速找到空闲节点。
在现实世界中的一个嵌入式程序中,Malloc()一次分配了一个固定内存块(通常称为内存池)。有时有多个内存池,每个内存池都有不同的节点。
但是值得一提的是,有几种方法可以进一步改善插入(需要自己分配记忆)并删除(需要自己发布记忆)。
如果我们仔细观察,我们可以注意到,内存的堆部分基本上是一个由基础操作系统(OS)管理的大字节阵列。OS。OS通过malloc(),free()。!路口
本文的重要内容如下:
a)数组表示连续内存。它可以存在于任何内存部分中,无论是数据,堆栈还是堆。
b)链接意味着非连续链接内存。它可以在任何内存部分中都存在,无论是堆,数据还是堆栈。
c)作为程序员,数据结构可以使我们在选择特定的数据结构甚至设计新的数据结构时具有更好的见解。例如,我们可以创建一个链接的数组。