我想檢查兩個節點 是相同的,這意味着它們具有 相同數量的孩子,那 那些孩子導致完全相同的 狀態。因此,我試圖比較 兩個節點上的子樹, 。我想知道是否可以使用 哈希來執行此平等檢查。
不,散列不應該被用來檢查平等。這不是它的目的。它最終可以幫助你發現物體是否不相等,但如果它們是平等的,它就不會告訴你任何東西。
相同的對象將產生相同的散列值,但是兩個不同的對象,其不相等也可以產生相同的散列。換句話說,如果散列值不同,你肯定知道對象是不同的。而已。
如果你想測試平等,你需要實現等於。在你的情況下,你的方法會遞歸併引發堆棧溢出。如果你的對象包含對自身的引用呢?
如果你想生成一個散列,你可以考慮數組的大小(以及它是否爲空的事實),但我不會嘗試使用數組中的對象的散列值,因爲潛在的無限循環。這並不完美,但它足夠好。
還有另一個激進的方法,可能會提供良好的結果。不是動態計算哈希值,而是爲每個Node對象實例設置一個隨機的int值(我的意思是在創建時爲所有人創建一次,並始終返回該值)。在你的情況下,你不會冒險數組中的對象實例的哈希值的風險無限循環。
如果散列值相等,則需要開始比較數組對象實例。
REM:如果節點包含其他屬性,那麼計算這些其他屬性的散列並忘記數組。開始調查數組內容/大小當且僅當散列在兩個對象之間是相同的。
REM2:評論提到DAG圖表,這意味着我們不會遇到遞歸性問題。但是,該條件不足以保證deepHashCode()將成功。而且,這也太過分了。有一個更有效的方法來解決這個問題。
如果由節點使用的散列方法只有使用該數組來計算散列值,那麼deepHashCode()可能工作。但這不會有效。如果散列方法使用其他節點屬性,那麼這些屬性也必須相同。
有一種更快的方式來比較節點的相等性。用一個唯一的數字標記每個節點實例。然後,爲了比較兩個節點,首先比較它們的數組大小。如果它是等於,則使用其唯一編號比較每個陣列中的節點。如果一個數組沒有「擁有」另一個節點,那麼我們沒有處理相同的節點。這個解決方案比遞歸更快。
我假設你建立的節點樹在某個時刻終止並且不是無限的? – justkt 2011-05-04 17:36:55
是的,它終止。 – efficiencyIsBliss 2011-05-04 17:45:29
@efficiencyIsBliss - 只要沒有子節點引用父節點,您應該可以在數組上使用deepHashCode和deepEquals。 – justkt 2011-05-04 18:18:00