From d42b3acd23486fb7bd0e09da23ec8e6b68527157 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Sun, 3 May 2020 10:25:19 +0200 Subject: [PATCH] redesign heaps to unify comparator interface --- alib2std/src/extensions/heaps/BinomialHeap.h | 169 +++++++++--------- alib2std/src/extensions/heaps/CppHeap.h | 65 +++---- alib2std/src/extensions/heaps/FibonacciHeap.h | 140 ++++++++------- .../test-src/extensions/heaps/HeapsTest.cpp | 16 +- 4 files changed, 196 insertions(+), 194 deletions(-) diff --git a/alib2std/src/extensions/heaps/BinomialHeap.h b/alib2std/src/extensions/heaps/BinomialHeap.h index 9cb97d3b1a..3e5293d76e 100644 --- a/alib2std/src/extensions/heaps/BinomialHeap.h +++ b/alib2std/src/extensions/heaps/BinomialHeap.h @@ -1,8 +1,8 @@ /* * BinomialHeap.h * - * Created on: Apr 7, 2016 - * Author: Jan Broz + * Created on: Apr 7, 2016 + * Author: Jan Broz */ #ifndef BINOMIAL_HEAP_INCLUDED @@ -12,82 +12,89 @@ namespace alib { -/// binomial heap used as mergeable priority queue -template< typename elem_t > +// binomial heap used as mergeable priority queue +template < typename T, typename Comparator > class BinomialHeap { + int threeWay ( const T & a, const T & b ) const { + bool less = _compare ( a, b ); + bool more = _compare ( b, a ); + if ( ! less && ! more ) + return 0; + else if ( less ) + return -1; + else + return 1; + } + public: - BinomialHeap( int (* compare)( const elem_t &, const elem_t & ) ); + BinomialHeap ( Comparator comparator = Comparator ( ) ) : _head( nullptr ), _size( 0 ), _compare ( comparator ) { + } - ~BinomialHeap(); + ~BinomialHeap ( ); - /// inserts a node with new value into the heap - void insert( const elem_t & value ); + // inserts a node with new value into the heap + void insert ( const T & value ); - /// finds the maximum value in the heap - const elem_t & getMax() const { - return (*searchMax( const_cast<Node**>(&_head) ))->value; + // finds the maximum value in the heap + const T & getMax ( ) const { + return ( * searchMax ( const_cast < Node * * > ( & _head ) ) )->value; } - /// finds and removes the maximum value from the heap - elem_t extractMax(); + // finds and removes the maximum value from the heap + T extractMax ( ); - /// merges this heap with another heap (!! this is a DESTRUCTIVE merge, heap in argument will be cleared !!) - void mergeWith( BinomialHeap<elem_t> && that ); + // merges this heap with another heap (!! this is a DESTRUCTIVE merge, heap in argument will be cleared !!) + void mergeWith ( BinomialHeap< T, Comparator > && that ); - size_t size() const { + size_t size ( ) const { return _size; } protected: struct Node { - elem_t value; - unsigned degree; + T value; + unsigned degree; Node * parent; Node * child; Node * sibling; - Node( const elem_t & val, unsigned deg = 0, Node * par = nullptr, Node * chld = nullptr, Node * sib = nullptr ) - : value(val), degree(deg), parent(par), child(chld), sibling(sib) {} + Node( const T & val, unsigned deg = 0, Node * par = nullptr, Node * chld = nullptr, Node * sib = nullptr ) + : value ( val ), degree ( deg ), parent ( par ), child ( chld ), sibling ( sib ) { } }; - Node * _head; ///< head of a singly linked list of binomial trees - size_t _size; ///< count of elements stored in the heap - int (* _compare)( const elem_t &, const elem_t & ); ///< user-defined comparator function + Node * _head; //< head of a singly linked list of binomial trees + size_t _size; //< count of elements stored in the heap + Comparator _compare; //< user-defined comparator function protected: - /// deletes one linked list of binomial trees + // deletes one linked list of binomial trees void deleteTreeList( Node * head ); - /// searches the linked list and returns address of variable pointing to the node with maximum value + // searches the linked list and returns address of variable pointing to the node with maximum value Node * * searchMax( Node * * head ) const; - /// merges linked lists from 2 binomial heaps and returns address of head of the new linked list + // merges linked lists from 2 binomial heaps and returns address of head of the new linked list - Node * mergeHeaps( Node * head1, Node * head2 ); - /// merges 2 linked lists of binomial trees and sorts the trees by increasing degree + Node * mergeHeaps( Node * head1, Node * head2 ); + // merges 2 linked lists of binomial trees and sorts the trees by increasing degree - Node * mergeListsByDeg( Node * head1, Node * head2 ); - /// reverses a linked list + Node * mergeListsByDeg( Node * head1, Node * head2 ); + // reverses a linked list - Node * reverseList( Node * head ); - /// links root of tree1 to root of tree2 (tree1 becomes child of tree2) - Node * linkTreeToTree( Node * root1, Node * root2 ); + Node * reverseList( Node * head ); + // links root of tree1 to root of tree2 (tree1 becomes child of tree2) + Node * linkTreeToTree( Node * root1, Node * root2 ); }; - -template< typename elem_t > -BinomialHeap<elem_t>::BinomialHeap( int (* compare)( const elem_t &, const elem_t & ) ) : _head( nullptr ), _size( 0 ), _compare( compare ) { -} - -template< typename elem_t > -BinomialHeap<elem_t>::~BinomialHeap() { +template < typename T, typename Comparator > +BinomialHeap < T, Comparator >::~BinomialHeap() { deleteTreeList( _head ); } -template< typename elem_t > -void BinomialHeap<elem_t>::deleteTreeList( Node * head ) { +template < typename T, typename Comparator > +void BinomialHeap < T, Comparator >::deleteTreeList( Node * head ) { while (head != nullptr) { Node * sibling = head->sibling; deleteTreeList( head->child ); @@ -96,51 +103,51 @@ void BinomialHeap<elem_t>::deleteTreeList( Node * head ) { } } -template< typename elem_t > -void BinomialHeap<elem_t>::insert( const elem_t & value ) { +template < typename T, typename Comparator > +void BinomialHeap < T, Comparator >::insert( const T & value ) { Node * newNode = new Node( value, 0, nullptr, nullptr, nullptr ); _head = mergeHeaps( _head, newNode ); // merge the current heap with the newNode, - // as if the newNode was a single-element heap + // as if the newNode was a single-element heap _size++; } -template< typename elem_t > -elem_t BinomialHeap<elem_t>::extractMax() { +template< typename T, typename Comparator > +T BinomialHeap< T, Comparator >::extractMax() { if ( _size == 0 ) throw std::out_of_range ( "Heap is empty." ); - Node * * ptrToMax = searchMax( &_head ); // find the node with maximum value + Node * * ptrToMax = searchMax( &_head ); // find the node with maximum value Node * max = *ptrToMax; - *ptrToMax = max->sibling; // disconnect it from the linked list + *ptrToMax = max->sibling; // disconnect it from the linked list - Node * chlHead = reverseList( max->child ); // merge them with the heap in reversed order + Node * chlHead = reverseList( max->child ); // merge them with the heap in reversed order _head = mergeHeaps( this->_head, chlHead ); _size--; - elem_t maxVal = max->value; - delete max; // extract the value from node and return it + T maxVal = max->value; + delete max; // extract the value from node and return it return maxVal; } -template< typename elem_t > -void BinomialHeap<elem_t>::mergeWith( BinomialHeap<elem_t> && that ) { - if (this->_compare != that._compare) // nodes of these heaps are sorted by different condition +template < typename T, typename Comparator > +void BinomialHeap < T, Comparator >::mergeWith( BinomialHeap< T, Comparator > && that ) { + if (this->_compare != that._compare) // nodes of these heaps are sorted by different condition throw std::logic_error("compare functions aren't equal, unable to merge"); - this->_head = mergeHeaps( this->_head, that._head ); // move the other heap into this heap + this->_head = mergeHeaps( this->_head, that._head ); // move the other heap into this heap that._head = nullptr; this->_size += that._size; that._size = 0; } -template< typename elem_t > -typename BinomialHeap<elem_t>::Node * * BinomialHeap<elem_t>::searchMax( Node * * head ) const { +template < typename T, typename Comparator > +typename BinomialHeap < T, Comparator >::Node * * BinomialHeap< T, Comparator >::searchMax( Node * * head ) const { Node * max = *head, * * ptrToMax = head; for (Node * actual = * head, * prev = nullptr; actual != nullptr; prev = actual, actual = actual->sibling) { - if (_compare( actual->value, max->value ) > 0) { + if ( threeWay ( actual->value, max->value ) > 0) { max = actual; ptrToMax = &prev->sibling; } @@ -148,15 +155,15 @@ typename BinomialHeap<elem_t>::Node * * BinomialHeap<elem_t>::searchMax( Node * return ptrToMax; } -template< typename elem_t > -typename BinomialHeap<elem_t>::Node * BinomialHeap<elem_t>::mergeHeaps( Node * head1, Node * head2 ) { +template < typename T, typename Comparator > +typename BinomialHeap < T, Comparator >::Node * BinomialHeap< T, Comparator >::mergeHeaps( Node * head1, Node * head2 ) { if ( ! head1 ) return head2; if ( ! head2 ) return head1; - head1 = mergeListsByDeg( head1, head2 ); // first, merge the lists of trees by their degrees + head1 = mergeListsByDeg( head1, head2 ); // first, merge the lists of trees by their degrees Node * actual = head1; Node * * toLink = & head1; @@ -164,45 +171,45 @@ typename BinomialHeap<elem_t>::Node * BinomialHeap<elem_t>::mergeHeaps( Node * h Node * next = actual->sibling; if (actual->degree != next->degree || (next->sibling && next->sibling->degree == actual->degree)) { - toLink = &actual->sibling; // not merging trees with same degree - actual = next; // or postponing the merge by 1 iteration - } else if (_compare( actual->value, next->value ) >= 0) { - actual->sibling = next->sibling; // merging 2 binomial trees with same degree - actual = linkTreeToTree( next, actual ); // 'next' becomes child of 'actual' + toLink = &actual->sibling; // not merging trees with same degree + actual = next; // or postponing the merge by 1 iteration + } else if ( threeWay ( actual->value, next->value ) >= 0) { + actual->sibling = next->sibling; // merging 2 binomial trees with same degree + actual = linkTreeToTree( next, actual ); // 'next' becomes child of 'actual' } else { - *toLink = next; // merging 2 binomial trees with same degree - actual = linkTreeToTree( actual, next ); // 'actual' becomes child of 'next' + *toLink = next; // merging 2 binomial trees with same degree + actual = linkTreeToTree( actual, next ); // 'actual' becomes child of 'next' } } return head1; } -template< typename elem_t > -typename BinomialHeap<elem_t>::Node * BinomialHeap<elem_t>::mergeListsByDeg( Node * head1, Node * head2 ) { +template < typename T, typename Comparator > +typename BinomialHeap < T, Comparator >::Node * BinomialHeap< T, Comparator >::mergeListsByDeg( Node * head1, Node * head2 ) { Node * newHead = nullptr; Node * * toLink = &newHead; while (head1 && head2) { if (head1->degree < head2->degree) { - *toLink = head1; // linking node from first list - toLink = &head1->sibling; // and moving first pointer + *toLink = head1; // linking node from first list + toLink = &head1->sibling; // and moving first pointer head1 = head1->sibling; } else { - *toLink = head2; // linking node from second list - toLink = &head2->sibling; // and moving second pointer + *toLink = head2; // linking node from second list + toLink = &head2->sibling; // and moving second pointer head2 = head2->sibling; } } if (!head1) - *toLink = head2; // list1 ended, link the rest of list2 + *toLink = head2; // list1 ended, link the rest of list2 else - *toLink = head1; // list2 ended, link the rest of list1 + *toLink = head1; // list2 ended, link the rest of list1 return newHead; } -template< typename elem_t > -typename BinomialHeap<elem_t>::Node * BinomialHeap<elem_t>::reverseList( Node * head ) { +template < typename T, typename Comparator > +typename BinomialHeap < T, Comparator >::Node * BinomialHeap< T, Comparator >::reverseList( Node * head ) { Node * prev = nullptr; while (head) { @@ -215,8 +222,8 @@ typename BinomialHeap<elem_t>::Node * BinomialHeap<elem_t>::reverseList( Node * return prev; } -template< typename elem_t > -typename BinomialHeap<elem_t>::Node * BinomialHeap<elem_t>::linkTreeToTree( Node * root1, Node * root2 ) { +template < typename T, typename Comparator > +typename BinomialHeap < T, Comparator >::Node * BinomialHeap< T, Comparator >::linkTreeToTree( Node * root1, Node * root2 ) { root1->parent = root2; root1->sibling = root2->child; root2->child = root1; diff --git a/alib2std/src/extensions/heaps/CppHeap.h b/alib2std/src/extensions/heaps/CppHeap.h index eeebc4a6f4..681e83556b 100644 --- a/alib2std/src/extensions/heaps/CppHeap.h +++ b/alib2std/src/extensions/heaps/CppHeap.h @@ -13,67 +13,58 @@ namespace alib { -/// binomial heap used as mergeable priority queue -template < typename elem_t > +/// heap build using C++ algorithm features +template < typename T, typename Comparator = std::less < T > > class CppHeap { public: - CppHeap( int (* compare)( const elem_t &, const elem_t & ) ); - - ~CppHeap(); + CppHeap( Comparator comparator = Comparator ( ) ) : m_comparator( comparator ) { + } - /// inserts a node with new value into the heap - void insert( const elem_t & value ); + // inserts a node with new value into the heap + void insert ( const T & value ); /// finds the maximum value in the heap - const elem_t & getMax() const { - return _data.front ( ); + const T & getMax ( ) const { + return m_data.front ( ); } /// finds and removes the maximum value from the heap - elem_t extractMax(); + T extractMax ( ); /// merges this heap with another heap (!! this is a DESTRUCTIVE merge, heap in argument will be cleared !!) - void mergeWith( CppHeap<elem_t> && that ); + void mergeWith ( CppHeap < T, Comparator > && that ); - size_t size() const { - return _data.size ( ); + size_t size ( ) const { + return m_data.size ( ); } protected: - int (* _compare)( const elem_t &, const elem_t & ); ///< user-defined comparator function - std::vector < elem_t > _data; + Comparator m_comparator; + std::vector < T > m_data; }; -template< typename elem_t > -CppHeap<elem_t>::CppHeap( int (* compare)( const elem_t &, const elem_t & ) ) : _compare( compare ) { -} - -template< typename elem_t > -CppHeap<elem_t>::~CppHeap() { -} - -template< typename elem_t > -void CppHeap<elem_t>::insert( const elem_t & value ) { - _data.push_back ( value ); - std::push_heap ( _data.begin ( ), _data.end ( ), _compare ); +template < typename T, typename Comparator > +void CppHeap < T, Comparator >::insert ( const T & value ) { + m_data.push_back ( value ); + std::push_heap ( m_data.begin ( ), m_data.end ( ), m_comparator ); } -template< typename elem_t > -elem_t CppHeap<elem_t>::extractMax() { - if ( _data.size ( ) == 0 ) +template < typename T, typename Comparator > +T CppHeap < T, Comparator >::extractMax ( ) { + if ( m_data.size ( ) == 0 ) throw std::out_of_range ( "Heap is empty." ); - elem_t res = _data.front ( ); - std::pop_heap ( _data.begin ( ), _data.end ( ), _compare ); - _data.pop_back ( ); + std::pop_heap ( m_data.begin ( ), m_data.end ( ), m_comparator ); + T res = std::move ( m_data.back ( ) ); + m_data.pop_back ( ); return res; } -template< typename elem_t > -void CppHeap<elem_t>::mergeWith( CppHeap<elem_t> && that ) { - _data.insert ( _data.end ( ), that._data.begin ( ), that._data.end ( ) ); - std::make_heap ( _data.begin ( ), _data.end ( ), _compare ); +template < typename T, typename Comparator > +void CppHeap < T, Comparator >::mergeWith( CppHeap < T, Comparator > && that ) { + m_data.insert ( m_data.end ( ), that.m_data.begin ( ), that.m_data.end ( ) ); + std::make_heap ( m_data.begin ( ), m_data.end ( ), m_comparator ); } } /* namespace alib */ diff --git a/alib2std/src/extensions/heaps/FibonacciHeap.h b/alib2std/src/extensions/heaps/FibonacciHeap.h index 73814ff942..2afae091d3 100644 --- a/alib2std/src/extensions/heaps/FibonacciHeap.h +++ b/alib2std/src/extensions/heaps/FibonacciHeap.h @@ -1,41 +1,53 @@ /* * FibonacciHeap.h * - * Created on: Apr 7, 2016 - * Author: Jan Broz + * Created on: Apr 7, 2016 + * Author: Jan Broz */ #ifndef FIBONACCI_HEAP_INCLUDED #define FIBONACCI_HEAP_INCLUDED #include <stdexcept> -#include <cmath> // maxDegree +#include <cmath> // maxDegree namespace alib { -/// fibonacci heap used as mergeable priority queue -template< typename elem_t > +// fibonacci heap used as mergeable priority queue +template < typename T, typename Comparator > class FibonacciHeap { + int threeWay ( const T & a, const T & b ) const { + bool less = _compare ( a, b ); + bool more = _compare ( b, a ); + if ( ! less && ! more ) + return 0; + else if ( less ) + return -1; + else + return 1; + } + public: - FibonacciHeap( int (* compare)( const elem_t &, const elem_t & ) ); + FibonacciHeap ( Comparator comparator = Comparator ( ) ) : _max( nullptr ), _size( 0 ), _compare( comparator ) { + } - ~FibonacciHeap(); + ~FibonacciHeap ( ); - /// inserts a node with new value into the heap - void insert( const elem_t & value ); + // inserts a node with new value into the heap + void insert ( const T & value ); - /// finds the maximum value in the heap - const elem_t & getMax() const { + // finds the maximum value in the heap + const T & getMax ( ) const { return _max->value; } - /// finds and removes the maximum value from the heap - elem_t extractMax(); + // finds and removes the maximum value from the heap + T extractMax ( ); - /// merges this heap with another heap (!! this is a DESTRUCTIVE merge, heap in argument will be cleared !!) - void mergeWith( FibonacciHeap<elem_t> && that ); + // merges this heap with another heap (!! this is a DESTRUCTIVE merge, heap in argument will be cleared !!) + void mergeWith ( FibonacciHeap< T, Comparator > && that ); - size_t size() const { + size_t size ( ) const { return _size; } @@ -45,33 +57,33 @@ public: protected: struct Node { - elem_t value; + T value; unsigned degree; - bool mark; + bool mark; Node * parent; Node * child; Node * prev; Node * next; - Node(const elem_t & val, unsigned deg = 0, Node * par = nullptr, Node * chld = nullptr, Node * pr = nullptr, Node * ne = nullptr) + Node(const T & val, unsigned deg = 0, Node * par = nullptr, Node * chld = nullptr, Node * pr = nullptr, Node * ne = nullptr) : value(val), degree(deg), mark(false), parent(par), child(chld), prev(pr), next(ne) {} }; - Node * _max; ///< pointer to cyclic doubly linked list of trees - size_t _size; ///< count of elements stored in the heap - int (* _compare)( const elem_t &, const elem_t & ); ///< user-defined comparator function + Node * _max; //< pointer to cyclic doubly linked list of trees + size_t _size; //< count of elements stored in the heap + Comparator _compare; //< user-defined comparator function protected: - /// deletes one linked list of trees + // deletes one linked list of trees void deleteTreeList( Node * head ); - /// connects doubly linked lists from 2 fibonacci heaps and returns address of head of the new linked list + // connects doubly linked lists from 2 fibonacci heaps and returns address of head of the new linked list void mergeHeaps( Node * & max1, Node * & max2 ); - /// goes through list of trees and merges trees with same degree + // goes through list of trees and merges trees with same degree void consolidate(); - /// links tree to child list of node + // links tree to child list of node void linkTreeToNode( Node * node, Node * tree ); // void printNode ( Node * node ); @@ -80,17 +92,13 @@ protected: }; -template< typename elem_t > -FibonacciHeap<elem_t>::FibonacciHeap ( int (* compare)( const elem_t &, const elem_t & ) ) : _max( nullptr ), _size( 0 ), _compare( compare ) { -} - -template< typename elem_t > -FibonacciHeap<elem_t>::~FibonacciHeap ( ) { +template < typename T, typename Comparator > +FibonacciHeap< T, Comparator >::~FibonacciHeap ( ) { deleteTreeList( _max ); } -template< typename elem_t > -void FibonacciHeap<elem_t>::deleteTreeList( Node * head ) { +template < typename T, typename Comparator > +void FibonacciHeap< T, Comparator >::deleteTreeList( Node * head ) { if ( ! head ) return; @@ -103,32 +111,32 @@ void FibonacciHeap<elem_t>::deleteTreeList( Node * head ) { } while (actual != head); } -template< typename elem_t > -void FibonacciHeap<elem_t>::insert( const elem_t & value ) { +template < typename T, typename Comparator > +void FibonacciHeap< T, Comparator >::insert( const T & value ) { Node * newNode = new Node( value, 0, nullptr, nullptr, nullptr, nullptr ); newNode->prev = newNode; - newNode->next = newNode; // make this node be a single-element cyclic list + newNode->next = newNode; // make this node be a single-element cyclic list if (!_max) { - _max = newNode; // this heap is empty, newNode becomes head of a linked list + _max = newNode; // this heap is empty, newNode becomes head of a linked list _size = 1; return; } - mergeHeaps( _max, newNode ); // link the newNode into the existing linked list + mergeHeaps( _max, newNode ); // link the newNode into the existing linked list - _max = _compare( _max->value, newNode->value ) > 0 ? _max : newNode; + _max = threeWay ( _max->value, newNode->value ) > 0 ? _max : newNode; _size++; } -template< typename elem_t > -elem_t FibonacciHeap<elem_t>::extractMax() { +template < typename T, typename Comparator > +T FibonacciHeap< T, Comparator >::extractMax() { if ( _max == nullptr ) throw std::out_of_range ( "Heap is empty." ); Node * z = _max; - elem_t maxVal = z->value; + T maxVal = z->value; if (z->child != nullptr) { Node * z1 = z->child; @@ -154,35 +162,35 @@ elem_t FibonacciHeap<elem_t>::extractMax() { return maxVal; } -template< typename elem_t > -void FibonacciHeap<elem_t>::mergeWith( FibonacciHeap<elem_t> && that ) { - if (this->_compare != that._compare) // nodes of these heaps are sorted by different condition +template < typename T, typename Comparator > +void FibonacciHeap< T, Comparator >::mergeWith( FibonacciHeap< T, Comparator > && that ) { + if (this->_compare != that._compare) // nodes of these heaps are sorted by different condition throw std::logic_error("compare functions aren't equal, unable to merge"); - mergeHeaps( this->_max, that._max ); // link the other heap into this heap - this->_max = _compare( _max->value, that._max->value ) > 0 ? this->_max : that._max; + mergeHeaps( this->_max, that._max ); // link the other heap into this heap + this->_max = threeWay ( _max->value, that._max->value ) > 0 ? this->_max : that._max; that._max = nullptr; this->_size += that._size; that._size = 0; } -template< typename elem_t > -void FibonacciHeap<elem_t>::mergeHeaps( Node * & max1, Node * & max2 ) { +template < typename T, typename Comparator > +void FibonacciHeap< T, Comparator >::mergeHeaps( Node * & max1, Node * & max2 ) { if ( ! max1 ) { - max1 = max2; // this heap is empty, move the content from the other heap inside + max1 = max2; // this heap is empty, move the content from the other heap inside } else if ( max2 ) { Node * max2prev = max2->prev; max2->prev->next = max1; - max2->prev = max1->prev; // this magicaly works even if the lists contain only one node + max2->prev = max1->prev; // this magicaly works even if the lists contain only one node max1->prev->next = max2; max1->prev = max2prev; } } -template< typename elem_t > -void FibonacciHeap<elem_t>::consolidate() { +template < typename T, typename Comparator > +void FibonacciHeap< T, Comparator >::consolidate() { unsigned maxDegree = log2( _size ); Node * * rootsByDegree = new Node * [ maxDegree + 1 ]; for (unsigned i = 0; i <= maxDegree; i++) @@ -201,7 +209,7 @@ void FibonacciHeap<elem_t>::consolidate() { Node * other = rootsByDegree[ actual->degree ]; rootsByDegree[ actual->degree ] = nullptr; - if (_compare( actual->value, other->value ) > 0) { + if ( threeWay ( actual->value, other->value ) > 0) { linkTreeToNode( actual, other ); } else { linkTreeToNode( other, actual ); @@ -217,14 +225,14 @@ void FibonacciHeap<elem_t>::consolidate() { _max = actual; Node * node = actual; do { - if (_compare( node->value, _max->value ) > 0) + if ( threeWay ( node->value, _max->value ) > 0) _max = node; node = node->next; } while ( node != actual ); } -template< typename elem_t > -void FibonacciHeap<elem_t>::linkTreeToNode( Node * node, Node * tree ) { +template < typename T, typename Comparator > +void FibonacciHeap< T, Comparator >::linkTreeToNode( Node * node, Node * tree ) { tree->prev->next = tree->next; tree->next->prev = tree->prev; @@ -237,16 +245,16 @@ void FibonacciHeap<elem_t>::linkTreeToNode( Node * node, Node * tree ) { mergeHeaps ( node->child, tree ); } -/*template < typename elem_t > -void FibonacciHeap<elem_t>::print() { +/*template < typename T, typename Comparator > +void FibonacciHeap< T, Comparator >::print() { if ( _max == nullptr ) std::cout << "Empty" << std::endl; printNode ( _max ); } -template < typename elem_t > -void FibonacciHeap < elem_t >::printNode ( Node * node ) { +template < typename T, typename Comparator > +void FibonacciHeap < T >::printNode ( Node * node ) { if ( node == nullptr ) return; @@ -259,13 +267,13 @@ void FibonacciHeap < elem_t >::printNode ( Node * node ) { } while ( node != actual ); } -template < typename elem_t > -void FibonacciHeap<elem_t>::checkConsystency() { +template < typename T, typename Comparator > +void FibonacciHeap< T, Comparator >::checkConsystency() { checkConsystency ( _max, nullptr ); } -template < typename elem_t > -void FibonacciHeap < elem_t >::checkConsystency ( Node * node, Node * parent ) { +template < typename T, typename Comparator > +void FibonacciHeap < T >::checkConsystency ( Node * node, Node * parent ) { if ( node == nullptr ) return; diff --git a/alib2std/test-src/extensions/heaps/HeapsTest.cpp b/alib2std/test-src/extensions/heaps/HeapsTest.cpp index 95225c3ae8..6c4cd63204 100644 --- a/alib2std/test-src/extensions/heaps/HeapsTest.cpp +++ b/alib2std/test-src/extensions/heaps/HeapsTest.cpp @@ -4,19 +4,15 @@ #include <alib/binomial_heap> #include <alib/fibonacci_heap> -static int comparator ( const int & a, const int & b ) { - return ( b < a ) - ( a < b ); -} - static int less ( const int & a, const int & b ) { return a < b; } TEST_CASE ( "Heaps Test", "[unit][std][bits]" ) { SECTION ( "Heaps" ) { - alib::BinomialHeap < int > bHeap ( comparator ); - alib::CppHeap < int > cHeap ( less ); - alib::FibonacciHeap < int > fHeap ( comparator ); + alib::BinomialHeap < int, int ( * ) ( const int &, const int & ) > bHeap ( less ); + alib::CppHeap < int, int ( * ) ( const int &, const int & ) > cHeap ( less ); + alib::FibonacciHeap < int, int ( * ) ( const int &, const int & ) > fHeap ( less ); auto size = [ & ] ( ) { int b = bHeap.size ( ); @@ -46,9 +42,9 @@ TEST_CASE ( "Heaps Test", "[unit][std][bits]" ) { }; auto mergeRandom = [ & ] ( unsigned limit ) { - alib::BinomialHeap < int > rbHeap ( comparator ); - alib::CppHeap < int > rcHeap ( comparator ); - alib::FibonacciHeap < int > rfHeap ( comparator ); + alib::BinomialHeap < int, int ( * ) ( const int &, const int & ) > rbHeap ( less ); + alib::CppHeap < int, int ( * ) ( const int &, const int & ) > rcHeap ( less ); + alib::FibonacciHeap < int, int ( * ) ( const int &, const int & ) > rfHeap ( less ); for ( unsigned i = 0; i < limit; ++ i ) { unsigned val = rand ( ) % 1000; -- GitLab