我一直在玩Binomial堆,而且我遇到了一個問題,我想在此討論,因爲我認爲它可能會涉及某些用戶實現Binomial Heap數據結構。二項式堆結構不會讓您指向節點(或迭代器)
我的目標是讓指向節點或句柄的指針,它們直接指向Binomial Heap內部節點,當我將它們插入到二項式堆中時,該節點又包含我的優先級值(通常爲整數)。 以這種方式,我將指針/句柄保持爲我所插入的內容,如果是這種情況,我可以使用binomial_heap_delete_node(node)
直接刪除值,就像迭代器一樣。
正如我們將看到的,這是不是可能與二項堆,這是因爲這種數據結構的架構。
與二項堆的主要問題是,在某些時候,你需要一個操作:binomial_heap_swap_parent_and_child(parent, child)
,你就需要在這兩個binomial_heap_decrease_key(node, key)
和binomial_heap_delete_node(node)
此操作。通過閱讀他們的名字,這些操作的目的非常明確。
所以,問題是如何binomial_heap_swap_parent_and_child(parent, child)
作品:在所有我看到了實現中,交換節點之間的優先值,不節點本身。 這將使節點的所有指針/句柄/迭代器無效,因爲它們仍然指向正確的節點,但這些節點不會具有您之前插入的同一優先級值,而是另一個節點。
如果我們看到Binomial堆(或一般的二叉樹)是如何構造的:這是非常合乎邏輯的:您有一個父節點,被許多孩子視爲「父母」,所以很多孩子指出它,但是那個父節點並不知道有多少個孩子(或者更重要的是哪個孩子)指向它,所以它會是不可能的這樣交換一個節點的位置。你唯一的選擇是交換整數優先級鍵,但是這將使節點的所有指針/句柄/迭代器無效。
注:可能的解決辦法NOT成爲其中代替使用binomial_heap_delete_node(node)
,一個可以只設置該節點的優先級,以除去到-999999999(或最小值)和彈出的最小節點出來:這不會解決問題,因爲binomial_heap_decrease_key(node, key)
仍然需要節點的父子交換操作,而唯一的解決辦法就是交換整數優先級。
我想知道是否有人在此問題之前發生過。 我認爲唯一的解決方案是使用另一個堆結構,比如Binary Heap,Pairing Heap或其他。
是的,你的解決方案是非常明顯的,就像在每個節點中添加一個指針向量一樣,將指向該節點的指針指向父節點。但是,無論是在每個節點添加更多數據,還是增加更多間接級別,我都會導致性能下降。所以現在,解決方案仍然使用另一個不是二項堆的數據結構。 –
@MarcoPagliaricci我想這很明顯,你沒有提及它;-)。但是你會遇到類似的問題與其他堆。例如。一個簡單的二進制堆,以通常的方式維護爲數組中的完整二叉樹:其中基本實現將數據存儲在數組中,要獲取刪除和減少鍵,必須將指針(或數組索引)存儲在數組中,指的是數據在別處。並且您必須將數據的反轉映射保存到完整的樹形數組中。這是我的一個實現(用於特殊目的):https://github.com/gene-ressler/lulu/blob/master/ext/lulu/pq.c – Gene
@MarcoPagliaricci NB:另一點是我不是確定你的意思是「殺死性能」。仔細實施,您將爲每個節點添加一個指針。這實際上是一種罕見的應用,每個節點4或8個字節和每個訪問的單個指針解引用將導致顯着差異。這正是C++對象引用引入的開銷,例如 – Gene