我正在为学校作业编写自己的双向链表实现,我在列表类中使用了一个名为Node
的内部节点类,它代表了彼此链接的列表节点(通常是链表的情况。)
class DoublyLinkedList<T>
{
class Node
{
T obj;
}
}
我想知道,对于包含许多节点的大型列表,由于每个Node
对象可能引用父列表类的实例,它是否是一个重要的开销和次优设计?作为一个非静态类肯定很方便 - 然后节点可能会改变父列表first
和last
引用,我发现这些引用对于封装很有用。
如果我将Node
设为静态,则不能再使用(没有明确的成员引用列表)来操纵父列表first
和last
,我必须接近它从反过来看 - 列表将通过自己的方法分配和操作节点,将它们相互链接,取消链接并自然调整其first
和last
值。
为了良好的设计和学习,我想知道什么是聪明的事情(c)(如果有的话)?
答案 0 :(得分:4)
如果内部类不是static
,那么对父类的隐式引用已经存在,您可以通过DoublyLinkedList.this
类中的Node
引用它。
在任何情况下,我都不明白为什么Node
类应该能够直接修改其父类的属性。更改列表的方法(因此first
和last
也应该是DoubleLinkedList
类,而不是Node
类。这完全适用于封装,Node
实例不应该知道它的包含位置或从外部使用它的方式。
答案 1 :(得分:2)
开销只是每个节点一个引用。假设除有效载荷之外的节点还具有先前链接和后向链接,额外引用父节点的开销将在额外的存储器使用中达到约33%(在3个现有存储器之上引用1个)。这是相当大的开销,特别是对于大节点计数和小负载。另一方面,有了更大的有效载荷,它就没那么重要了。
但是,一般情况下,我不会对有效负载大小做出假设,并使Node类static
。