如果这被认为是偏离主题的话我很抱歉,但我希望数据结构的设计与编程实践的相关性足以与此相关。
我正在学习C和C ++,并且已经介绍了数组和内存分配,我们开始查看链表。讲师表示他们的优势主要是能够在不复制整个结构的情况下添加/删除节点 - 我可以看到,为了将节点添加到数组,我们需要免费的existing_array_size + node_size
记忆,尽管我们将删除整个existing_array_size
。即使删除条目,我们也可能想要再次复制整个结构。
使用链表,我们支付执行时间的代价(在遍历潜在的n
个节点时只需查找和删除一个),以便提高内存效率。
val of ll0
ptr to ll1
...
val of ll1
ptr to ll2
...
...
val of lln
null ptr
一切都很好。但是,我想到的是什么(可能是由于它是全新的而且没有正确理解,请原谅我)是我们为n+1
指针者浪费了大量的记忆(我预计这是关于这是否真的是一个'浪费'..它是方法所必需的,但不包含任何实际的值)。
对我来说似乎更明显的结构 尤其是无序列表的 如下所示,取一个ptr to start
:
(start) ptr to end
val of 0
val of 1
...
val of n
(end) null ptr
到目前为止,这看起来像一个数组..让我们删除一个值:
(start) ptr to end
val of 0
val of 1
...
(deleted0) val of m (= null)
...
val of n
(end) ptr to deleted0
现在插入一个值x
:
(start) ptr to end
val of 0
val of 1
...
val of m (= x)
...
val of n
(end) null ptr
我现在看到的一个问题只是在我输入时,如果我们需要插入没有删除,或者甚至必须保留多个指向删除的指针,这些指针会延伸到“end
以下”,我们如果它存在,则不允许覆盖内存中的其他项目。
那么在那个例子中,为什么不表现得像链接列表,整个结构作为“节点”?删除2项:
(start) ptr to end
val of 0
val of 1
...
val of m (= x)
...
(deleted0) val of a (= null)
...
(deleted1) val of b (= null)
...
val of n
(end) ptr to start1
...
...
(start1) ptr to end1
(end1) ptr to deleted0
ptr to deleted1
好的,假设我们现在因删除而有一些空白但没有要插入的内容。也许我们想要稍微清理一下,通过填充start1
等start2
结构来“缩小”是相当简单的。start(0)
中有空格我想我们会有别无选择,只能将其复制出来。
请注意,end
不是'end',而是值的结尾,我们在其中寻找指向内部空闲空间的指针结构
n
,所需的最大空间往往为n
,并且与num_insertions/num_deletions
成比例*'最坏的情况'是每个其他元素都被删除的时候,我们基本上都有一个链接列表,其中包含所有指针。
在开始愤怒地输入之前,你可能没有兴趣阅读这篇文章:
那么我的问题是什么?!
简单:这个想法出了什么问题(除非当然使用它/非常相似的东西,在这种情况下 - 它叫什么?) - 是否只是我们想要插入/删除的速度总是很清楚或者为了节省内存中的通常空间,这是多余的?
谢谢,对于长篇文章感到抱歉,我觉得需要几个例子才能明确。
答案 0 :(得分:1)
首先,请记住我们有不同的结构,因为我们有不同的要求。您的数据结构可能非常适合某些应用程序,但它肯定不适合作为链接列表的通用替代。
以下是三个数据结构无法替换链接列表的示例:
您专注于删除,这很容易,因为您只是将该地点标记为已删除(这种方式并非总是可行。您的数据结构可能不一定存储指针,因此您可以使用NULL作为标记)。 / p>
但是,如果阵列已满,您需要在中间插入什么?然后,您将被迫移动数组的所有内容(向左或向右移动到最近的孔,如果已满,则移动到数组的末尾),这非常昂贵。
如果将结构用作队列,请考虑结构会发生什么。您将在最后连续插入(即使用realloc
放大数组)并从开头标记为已删除。实际上,你的数组的大小会严格增加,即注定要失败。
链表的一个好处是,无论实际链接如何变化,数据都在同一个内存位置持久存在。想象一下,有人引用了列表中节点的数据(即指向节点数据的指针)。如果将这些数据存储在数组中,那么任何数据移位(插入时不可避免)都会使这些指针无效。但是,对于链接列表,无论您在链接列表中插入或删除的内容和位置,数据地址都保持不变(除非您删除该特定节点!)