2013-03-09 55 views
2

我正在編寫自己的學校派遣雙鏈表的實現,我在列表類中使用一個名爲Node的內部節點類,它表示相互鏈接的列表節點(通常是鏈接列表的情況) 。這個特定的內部非靜態類是否有很大的開銷?

class DoublyLinkedList<T> 
{ 
    class Node 
    { 
     T obj; 
    } 
} 

我不知道,對於許多節點的大名單,因爲每個Node對象可參照父列表類的一個實例,它是一個顯著的開銷和次優的設計?將它作爲非靜態類確實很方便 - 然後節點可以更改父列表firstlast引用,我發現這些引用對於封裝非常有用。

如果我讓Node靜態的,它不再是(沒有明確的成員引用到列表中)用來操縱父列表firstlast,我必須從周圍的其他方式接近這一切 - 名單將分配並通過自己的方法操作節點,即將它們鏈接到彼此,取消鏈接並自然調整其值firstlast值。

爲了良好的設計和學習,我想知道什麼是智能做事(c)(如果有)?

回答

2

開銷將是每個節點恰好一個參考。假設除有效負載之外的節點也有先前的鏈接和反向鏈接,額外引用父節點的開銷在額外的內存使用中將達到約33%(在3個現有節點的基礎上爲1個引用)。這是相當大的開銷,特別是對於大型節點計數和小型有效負載。另一方面,對於更大的有效載荷,這並不重要。

一般來說,我不會對有效載荷大小做一個假設,並且使節點類static

4

如果內部類不是static那麼對父類的隱式引用已經存在,您可以通過DoublyLinkedList.thisNode類中引用它。

在任何情況下,我不明白爲什麼Node類應該能夠直接修改其父類的屬性。改變列表的方法(所以firstlast也應該是DoubleLinkedList類,而不是直接Node類。這正是封裝,一個Node實例不應該知道它包含的位置或從外部使用它的方式。

+0

謝謝。這不是我的第一個雙向鏈表實現。我曾經按照你的建議去做,但出於一些有趣的理由認爲它值得一試。我現在重構了一個靜態Node類。 – amn 2013-03-09 14:45:53

+0

我沒有看到讓它變成「靜態」的地步。如果你接受你的'Node'類使用對列表實例的引用,那麼這兩個類是緊密耦合的:一個'Node'實例沒有它的父類沒有任何意義(因爲它使用對它的引用),所以沒有任何意義允許在不包含'DoublyLinkedList'的封閉實例的情況下實例化。如果你讓它成爲'靜態',你可以通過設計讓它瞬間完成,這樣就可以打破整個行爲。 – Jack 2013-03-09 15:11:22

+0

那麼,對我來說,開銷是決定性的因素,而且爲了方便起見,我把課程定義爲非靜態的。我將它定義爲靜態的,它解決了不必要的開銷問題,並將引用列表的方法從節點類中移出到列表類本身中。在大多數方面,我沒有失去任何東西,但獲得了規模和速度優勢。類之間的耦合現在也更加鬆散,並且代碼更具可移植性(對我而言並不重要),因爲並非所有的OOP語言都支持非靜態類。 – amn 2013-03-10 10:52:08

相關問題