From 754c04d80ddfe995ba67d48342c470a32375f2e4 Mon Sep 17 00:00:00 2001 From: weiz Date: Tue, 8 Mar 2022 18:06:00 +0800 Subject: [PATCH] Fix: pairing heap don't work then using Delete not DelateMin to delete minimum --- pairing/pairing_heap.go | 12 +++++++----- pairing/pairing_heap_test.go | 33 ++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/pairing/pairing_heap.go b/pairing/pairing_heap.go index 2dc7542..281329f 100644 --- a/pairing/pairing_heap.go +++ b/pairing/pairing_heap.go @@ -6,8 +6,9 @@ package pairing import ( - heap "github.com/theodesp/go-heaps" "fmt" + + heap "github.com/theodesp/go-heaps" ) // PairHeap implements the Extended interface @@ -16,7 +17,7 @@ var _ heap.Extended = (*PairHeap)(nil) // PairHeap is an implementation of a Pairing Heap. // The zero value for PairHeap Root is an empty Heap. type PairHeap struct { - root *node + root *node } // node contains the current item and the list if the sub-heaps @@ -126,12 +127,11 @@ func (p *PairHeap) Insert(item heap.Item) heap.Item { return item } - // toDelete details what item to remove in a node call. type toDelete int const ( - removeItem toDelete = iota // removes the given item + removeItem toDelete = iota // removes the given item removeMin // removes min item in the heap ) @@ -162,6 +162,9 @@ func (p *PairHeap) deleteItem(item heap.Item, typ toDelete) heap.Item { node := p.root.findNode(item) if node == nil { return nil + } else if node == p.root { + result = *p.root + p.root = mergePairs(p.root, p.root.children) } else { children := node.detach() p.root.children = append(p.root.children, children...) @@ -212,7 +215,6 @@ func (p *PairHeap) Find(item heap.Item) heap.Item { return found } - // Do calls function cb on each element of the PairingHeap, in order of appearance. // The behavior of Do is undefined if cb changes *p. func (p *PairHeap) Do(it heap.ItemIterator) { diff --git a/pairing/pairing_heap_test.go b/pairing/pairing_heap_test.go index 1e55748..b0e7575 100644 --- a/pairing/pairing_heap_test.go +++ b/pairing/pairing_heap_test.go @@ -1,13 +1,14 @@ package pairing import ( - "testing" - "github.com/stretchr/testify/suite" - "github.com/stretchr/testify/assert" - heap "github.com/theodesp/go-heaps" "fmt" "math/rand" + "testing" "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + heap "github.com/theodesp/go-heaps" ) type PairingHeapTestSuite struct { @@ -156,8 +157,8 @@ func (suite *PairingHeapTestSuite) TestFind() { suite.heap.Insert(Int(4)) item = suite.heap.Find(Int(4)) - assert.NotNil(suite.T(),item) - assert.Equal(suite.T(),item, Int(4)) + assert.NotNil(suite.T(), item) + assert.Equal(suite.T(), item, Int(4)) suite.heap.Insert(Int(8)) suite.heap.Insert(Int(2)) @@ -166,8 +167,8 @@ func (suite *PairingHeapTestSuite) TestFind() { suite.heap.Insert(Int(9)) item = suite.heap.Find(Int(9)) - assert.NotNil(suite.T(),item) - assert.Equal(suite.T(),item, Int(9)) + assert.NotNil(suite.T(), item) + assert.Equal(suite.T(), item, Int(9)) testMinHeapInvariance(suite) } @@ -181,6 +182,20 @@ func (suite *PairingHeapTestSuite) TestAdjust() { testMinHeapInvariance(suite) } +func (suite *PairingHeapTestSuite) TestDeleteBug() { + vs := []int{3, 4, 5, 6, 7, 8} + for _, v := range vs { + suite.heap.Insert(Int(v)) + } + assert.Equal(suite.T(), Int(3), suite.heap.Delete(Int(3))) + assert.Nil(suite.T(), suite.heap.Find(Int(3))) + i := suite.heap.DeleteMin() + assert.Equal(suite.T(), Int(4), i) + + assert.Equal(suite.T(), Int(6), suite.heap.Delete(Int(6))) + assert.Nil(suite.T(), suite.heap.Find(Int(6))) +} + func (suite *PairingHeapTestSuite) TestDelete() { for _, v := range rang(10) { suite.heap.Insert(v) @@ -194,4 +209,4 @@ func (suite *PairingHeapTestSuite) TestDelete() { func Int(value int) heap.Integer { return heap.Integer(value) -} \ No newline at end of file +}