PairNode<Etype> * PairHeap<Etype>::CombineSiblings( PairNode<Etype> *FirstSibling ) { if( FirstSibling->NextSibling == NULL ) return FirstSibling; // Allocate the array Vector<PairNode<Etype> *> TreeArray( CurrentSize ); // Store the subtrees in an array int NumSiblings; for( NumSiblings = 0; FirstSibling != NULL; NumSiblings++ ) { TreeArray[ NumSiblings ] = FirstSibling; FirstSibling->Prev->NextSibling = NULL; // break links FirstSibling = FirstSibling->NextSibling; } TreeArray[ NumSiblings ] = NULL; // Combine the subtrees two at a time, going left to right int i; for( i = 0; i+1 < NumSiblings; i+=2 ) CompareAndLink( TreeArray[ i ], TreeArray[ i + 1 ] ); int j = i - 2; // j has the result of the last CompareAndLink. // If an odd number of trees, get the last one if( j == NumSiblings - 3 ) CompareAndLink( TreeArray[ j ], TreeArray[ j + 2 ] ); // Now go right to left, merging last tree with // next to last. The result becomes the new last. for( ; j >= 2; j -= 2 ) CompareAndLink( TreeArray[ j - 2 ], TreeArray[ j ] ); PairNode<Etype> *Result = TreeArray[ 0 ]; return Result; }
PairHeap CombineSiblings( Position FirstSibling ) { static Position TreeArray[ MaxSiblings ]; int i, j, NumSiblings; /* If only one tree, return it */ if( FirstSibling->NextSibling == NULL ) return FirstSibling; /* Place each subtree in TreeArray */ for( NumSiblings = 0; FirstSibling != NULL; NumSiblings++ ) { TreeArray[ NumSiblings ] = FirstSibling; FirstSibling->Prev->NextSibling = NULL; /* Break links */ FirstSibling = FirstSibling->NextSibling; } TreeArray[ NumSiblings ] = NULL; /* Combine the subtrees two at a time, */ /* going left to right */ for( i = 0; i + 1 < NumSiblings; i += 2 ) TreeArray[ i ] = CompareAndLink( TreeArray[ i ], TreeArray[ i + 1 ] ); /* j has the result of the last CompareAndLink */ /* If an odd number of trees, get the last one */ j = i - 2; if( j == NumSiblings - 3 ) TreeArray[ j ] = CompareAndLink( TreeArray[ j ], TreeArray[ j + 2 ] ); /* Now go right to left, merging last tree with */ /* next to last. The result becomes the new last */ for( ; j >= 2; j -= 2 ) TreeArray[ j - 2 ] = CompareAndLink( TreeArray[ j - 2 ], TreeArray[ j ] ); return TreeArray[ 0 ]; }
PairNode<Etype> * PairHeap<Etype>::Insert( const Etype & X ) { PairNode<Etype> *NewNode = new PairNode<Etype>( X ); CurrentSize++; if( Root == NULL ) Root = NewNode; else CompareAndLink( Root, NewNode ); return NewNode; }
PairHeap Insert( ElementType Item, PairHeap H, Position *Loc ) { Position NewNode; NewNode = malloc( sizeof( struct PairNode ) ); if( NewNode == NULL ) FatalError( "Out of space!!!" ); NewNode->Element = Item; NewNode->LeftChild = NewNode->NextSibling = NULL; NewNode->Prev = NULL; *Loc = NewNode; if( H == NULL ) return NewNode; else return CompareAndLink( H, NewNode ); }
PairHeap DecreaseKey( Position P, ElementType Delta, PairHeap H ) { if( Delta < 0 ) Error( "DecreaseKey called with negative Delta" ); P->Element -= Delta; if( P == H ) return H; if( P->NextSibling != NULL ) P->NextSibling->Prev = P->Prev; if( P->Prev->LeftChild == P ) P->Prev->LeftChild = P->NextSibling; else P->Prev->NextSibling = P->NextSibling; P->NextSibling = NULL; return CompareAndLink( H, P ); }
void PairHeap<Etype>::DecreaseKey( PairNode<Etype> *P, const Etype & NewVal ) { if( P->Element < NewVal ) cerr << "DecreaseKey called with larger value!" << endl; else { P->Element = NewVal; if( P != Root ) { if( P->NextSibling != NULL ) P->NextSibling->Prev = P->Prev; if( P->Prev->LeftChild == P ) P->Prev->LeftChild = P->NextSibling; else P->Prev->NextSibling = P->NextSibling; P->NextSibling = NULL; CompareAndLink( Root, P ); } } }