Binomial heapsΒΆ
A free binary tree container is defined according to
Object subclass: #CTBinomialHeap
	instanceVariableNames: 'representation'
	classVariableNames: ''
	package: 'Containers-BinomialHeap'
and its responsibility is to direct and manage objects of types
Object subclass: #CTBinomialTree
	instanceVariableNames: 'content children'
	classVariableNames: ''
	package: 'Containers-BinomialHeap'
as actual representation for the underlying structure. The simpler container is the empty tree,
where
"CTBinomialHeap class, protocol requirements"
empty
   ^ self new
        representation: nil;
        yourself
In general, we use collections and then build trees out of them. On one hand,
using ArrayedCollection objects
where
"CTBinomialHeapTest, protocol tests"
tree: aCollection
   ^ aCollection asBinomialHeap
"Collection, protocol *Containers-BinomialHeap"
asBinomialHeap
   ^ self asBinaryTree: CTBinomialHeap
and
"CTBinomialHeap class, protocol instance creation"
withArrayedCollection: aCollection
   ^ aCollection ifEmpty: [ self empty ] ifNotEmpty: [ 
        self new yourself: [ :tree | 
           tree representation: (aCollection
                  bisect: [ :l :r | tree merge: l with: r ]
                  baseBlock: [ :each | 0 -> (CTBinomialTree leaf: each) ~~> nil ]) ] ]
uses
"CTBinomialHeap, protocol adding"
merge: trees with: otherTrees
   ^ trees ifNil: [ otherTrees ] ifNotNil: [ 
        otherTrees ifNil: [ trees ] ifNotNil: [ 
           | aTree anotherTree allButFirstTrees allButFirstOtherTrees aRank anotherRank |
           "Getting rests of both collections of trees to merge."
           allButFirstTrees := trees nextLink.
           allButFirstOtherTrees := otherTrees nextLink.
           "Getting current topmost trees."
           aTree := trees value.
           anotherTree := otherTrees value.
           "Getting ranks."
           aRank := aTree key.
           anotherRank := anotherTree key.
           "Rank comparison via `#key`."
           aRank < anotherRank
              ifTrue: [ 
              aTree ~~> (self merge: allButFirstTrees with: otherTrees) ]
              ifFalse: [ 
                 anotherRank < aRank
                    ifTrue: [ 
                    anotherTree
                    ~~> (self merge: trees with: allButFirstOtherTrees) ]
                    ifFalse: [ 
                       | binomialTree mergedTrees |
                       "Invariant: both `aTree` and `anotherTree` have the *same* rank."
                       binomialTree := aTree value linkBinomialTree:
                                          anotherTree value.
                       mergedTrees := self
                                         merge: allButFirstTrees
                                         with: allButFirstOtherTrees.
                       self pushTree: aRank + 1 -> binomialTree onTrees: mergedTrees ] ] ] ]
that delegates on both
"CTBinomialHeap, protocol adding"
pushTree: anAssociation onTrees: trees
   ^ trees ifNil: [ anAssociation ~~> trees ] ifNotNil: [ 
        | carAssociation rank |
        rank := anAssociation key.
        carAssociation := trees value.
        rank < carAssociation key
           ifTrue: [ anAssociation ~~> trees ]
           ifFalse: [ 
              self
                 pushTree: rank + 1
                    ->
                    (anAssociation value linkBinomialTree: carAssociation value)
                 onTrees: trees nextLink ] ]
and
"CTBinomialTree, protocol as yet unclassified"
linkBinomialTree: aTree
   | x |
   x := aTree content.
   ^ content < x
        ifTrue: [ self class node: content children: aTree ~~> children ]
        ifFalse: [ self class node: x children: self ~~> aTree children ]
to finally build the tree. On the other hand, using Collection objects
where
"CTBinomialHeap class, protocol instance creation"
withCollection: aCollection
   ^ aCollection
        inject: self empty
        into: [ :aBinaryTree :each | aBinaryTree push: each ]
uses
"CTBinomialHeap, protocol adding"
push: x
   representation := self
                        pushTree: 0 -> (CTBinomialTree leaf: x)
                        onTrees: representation
repeatedly. The two cases above can be redone with shuffled collections, both
and
respectively.