Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
pairing_heap.h
Go to the documentation of this file.
1/*
2 * vim: ts=4 sw=4 et tw=0 wm=0
3 *
4 * libvpsc - A solver for the problem of Variable Placement with
5 * Separation Constraints.
6 *
7 * Copyright (C) 2005 Mark Allen Weiss
8 * Copyright (C) 2005-2008 Monash University
9 *
10 * ----------------------------------------------------------------------------
11 * Pairing heap datastructure implementation:
12 * Based on example code in "Data structures and Algorithm Analysis in C++"
13 * by Mark Allen Weiss, used and released under the LGPL by permission
14 * of the author.
15 * No promises about correctness. Use at your own risk!
16 * ----------------------------------------------------------------------------
17 *
18 * This library is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU Lesser General Public
20 * License as published by the Free Software Foundation; either
21 * version 2.1 of the License, or (at your option) any later version.
22 * See the file LICENSE.LGPL distributed with the library.
23 *
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
27 *
28 * Author(s): Mark Allen Weiss
29 * Tim Dwyer
30*/
31
32#ifndef VPSC_PAIRING_HEAP_H
33#define VPSC_PAIRING_HEAP_H
34
35#include <cstdlib>
36#include <fstream>
37#include <vector>
38#include <list>
39
40#include "libvpsc/assertions.h"
41
42class Underflow { };
43
44// Pairing heap class
45//
46// CONSTRUCTION: with no parameters
47//
48// ******************PUBLIC OPERATIONS*********************
49// PairNode & insert( x ) --> Insert x
50// deleteMin( minItem ) --> Remove (and optionally return) smallest item
51// T findMin( ) --> Return smallest item
52// bool isEmpty( ) --> Return true if empty; else false
53// void makeEmpty( ) --> Remove all items
54// void decreaseKey( PairNode p, newVal )
55// --> Decrease value in node p
56// ******************ERRORS********************************
57// Throws Underflow as warranted
58
59
60template <class T>
62{
67
68 PairNode( const T & theElement ) :
69 element( theElement ),
70 leftChild(nullptr), nextSibling(nullptr), prev(nullptr)
71 { }
72};
73
74template <class T, class TCompare>
75class PairingHeap;
76
77template <class T,class TCompare>
78std::ostream& operator <<(std::ostream &os, const PairingHeap<T,TCompare> &b);
79
80template <class T, class TCompare = std::less<T> >
82{
83#ifndef SWIG
84 friend std::ostream& operator<< <T,TCompare> (std::ostream &os, const PairingHeap<T,TCompare> &b);
85#endif
86public:
87 PairingHeap() : root(nullptr), counter(0), siblingsTreeArray(5) { }
88 PairingHeap(const PairingHeap & rhs) {
89 // uses operator= to make deep copy
90 *this = rhs;
91 }
93 const PairingHeap & operator=( const PairingHeap & rhs );
94 bool isEmpty() const { return root == nullptr; }
95 unsigned size() const { return counter; }
96 PairNode<T> *insert( const T & x );
97 const T & findMin( ) const;
98 void deleteMin( );
99 const T extractMin( ) {
100 T v = findMin();
101 deleteMin();
102 return v;
103 }
104 void makeEmpty() {
106 root = nullptr;
107 counter = 0;
108 }
109 void decreaseKey( PairNode<T> *p, const T & newVal );
111protected:
112 // Destructively gets the root for merging into another heap.
114 PairNode<T> *r=root;
115 root=nullptr;
117 counter=0;
118 return r;
119 }
120 TCompare lessThan;
121private:
123 unsigned counter;
124
125 // Used by PairingHeap::combineSiblings(). We keep this as member
126 // variable to save some vector resize operations during subsequent uses.
127 std::vector<PairNode<T> *> siblingsTreeArray;
128
129 void reclaimMemory( PairNode<T> *t ) const;
130 void compareAndLink( PairNode<T> * & first, PairNode<T> *second ) const;
133};
134
135
140template <class T,class TCompare>
143{
144 PairNode<T> *newNode = new PairNode<T>( x );
145
146 if( root == nullptr )
147 root = newNode;
148 else
149 compareAndLink( root, newNode );
150 counter++;
151 return newNode;
152}
153
158template <class T,class TCompare>
160{
161 if( isEmpty( ) )
162 throw Underflow( );
163 return root->element;
164}
169template <class T,class TCompare>
171{
172 if( isEmpty( ) )
173 throw Underflow( );
174
175 PairNode<T> *oldRoot = root;
176
177 if( root->leftChild == nullptr )
178 root = nullptr;
179 else
180 root = combineSiblings( root->leftChild );
181 COLA_ASSERT(counter);
182 counter--;
183 delete oldRoot;
184}
185
189template <class T,class TCompare>
192{
193 if( this != &rhs )
194 {
195 makeEmpty( );
196 root = clone( rhs.root );
197 counter = rhs.size();
198 }
199
200 return *this;
201}
202
207template <class T,class TCompare>
209{
210 if( t != nullptr )
211 {
212 reclaimMemory( t->leftChild );
213 reclaimMemory( t->nextSibling );
214 delete t;
215 }
216}
217
225template <class T,class TCompare>
227 const T & newVal )
228{
229 COLA_ASSERT(!lessThan(p->element,newVal)); // newVal cannot be bigger
230 p->element = newVal;
231 if( p != root )
232 {
233 if( p->nextSibling != nullptr )
234 p->nextSibling->prev = p->prev;
235 if( p->prev->leftChild == p )
236 p->prev->leftChild = p->nextSibling;
237 else
239
240 p->nextSibling = nullptr;
241 compareAndLink( root, p );
242 }
243}
244
248template <class T,class TCompare>
250{
251 unsigned rhsSize;
252 PairNode<T> *broot=rhs->removeRootForMerge(rhsSize);
253 if (root == nullptr) {
254 root = broot;
255 } else {
256 compareAndLink(root, broot);
257 }
258 counter+=rhsSize;
259}
260
269template <class T,class TCompare>
271compareAndLink( PairNode<T> * & first,
272 PairNode<T> *second ) const
273{
274 if( second == nullptr )
275 return;
276
277 if( lessThan(second->element,first->element) )
278 {
279 // Attach first as leftmost child of second
280 second->prev = first->prev;
281 first->prev = second;
282 first->nextSibling = second->leftChild;
283 if( first->nextSibling != nullptr )
284 first->nextSibling->prev = first;
285 second->leftChild = first;
286 first = second;
287 }
288 else
289 {
290 // Attach second as leftmost child of first
291 second->prev = first;
292 first->nextSibling = second->nextSibling;
293 if( first->nextSibling != nullptr )
294 first->nextSibling->prev = first;
295 second->nextSibling = first->leftChild;
296 if( second->nextSibling != nullptr )
297 second->nextSibling->prev = second;
298 first->leftChild = second;
299 }
300}
301
307template <class T,class TCompare>
310{
311 if( firstSibling->nextSibling == nullptr )
312 return firstSibling;
313
314 // Store the subtrees in an array
315 int numSiblings = 0;
316 for( ; firstSibling != nullptr; numSiblings++ )
317 {
318 if( numSiblings == (int)siblingsTreeArray.size( ) )
319 siblingsTreeArray.resize( numSiblings * 2 );
320 siblingsTreeArray[ numSiblings ] = firstSibling;
321 firstSibling->prev->nextSibling = nullptr; // break links
322 firstSibling = firstSibling->nextSibling;
323 }
324 if( numSiblings == (int)siblingsTreeArray.size( ) )
325 siblingsTreeArray.resize( numSiblings + 1 );
326 siblingsTreeArray[ numSiblings ] = nullptr;
327
328 // Combine subtrees two at a time, going left to right
329 int i = 0;
330 for( ; i + 1 < numSiblings; i += 2 )
331 compareAndLink( siblingsTreeArray[ i ], siblingsTreeArray[ i + 1 ] );
332
333 int j = i - 2;
334
335 // j has the result of last compareAndLink.
336 // If an odd number of trees, get the last one.
337 if( j == numSiblings - 3 )
338 compareAndLink( siblingsTreeArray[ j ], siblingsTreeArray[ j + 2 ] );
339
340 // Now go right to left, merging last tree with
341 // next to last. The result becomes the new last.
342 for( ; j >= 2; j -= 2 )
343 compareAndLink( siblingsTreeArray[ j - 2 ], siblingsTreeArray[ j ] );
344 return siblingsTreeArray[ 0 ];
345}
346
351template <class T,class TCompare>
354{
355 if( t == nullptr )
356 return nullptr;
357 else
358 {
359 PairNode<T> *p = new PairNode<T>( t->element );
360 if( ( p->leftChild = clone( t->leftChild ) ) != nullptr )
361 p->leftChild->prev = p;
362 if( ( p->nextSibling = clone( t->nextSibling ) ) != nullptr )
363 p->nextSibling->prev = p;
364 return p;
365 }
366}
367
368template <class T,class TCompare>
369std::ostream& operator <<(std::ostream &os, const PairingHeap<T,TCompare> &b)
370{
371 os<<"Heap:";
372 if (b.root != nullptr) {
373 PairNode<T> *r = b.root;
374 std::list<PairNode<T>*> q;
375 q.push_back(r);
376 while (!q.empty()) {
377 r = q.front();
378 q.pop_front();
379 if (r->leftChild != nullptr) {
380 os << *r->element << ">";
381 PairNode<T> *c = r->leftChild;
382 while (c != nullptr) {
383 q.push_back(c);
384 os << "," << *c->element;
385 c = c->nextSibling;
386 }
387 os << "|";
388 }
389 }
390 }
391 return os;
392}
393
394#endif /* VPSC_PAIRING_HEAP_H */
unsigned size() const
void deleteMin()
Remove the smallest item from the priority queue.
void decreaseKey(PairNode< T > *p, const T &newVal)
Change the value of the item stored in the pairing heap.
const T & findMin() const
Find the smallest item in the priority queue.
PairNode< T > * removeRootForMerge(unsigned &size)
void merge(PairingHeap< T, TCompare > *rhs)
Merges rhs into this pairing heap by inserting its root.
std::vector< PairNode< T > * > siblingsTreeArray
bool isEmpty() const
PairingHeap(const PairingHeap &rhs)
void compareAndLink(PairNode< T > *&first, PairNode< T > *second) const
Internal method that is the basic operation to maintain order.
TCompare lessThan
PairNode< T > * insert(const T &x)
Insert item x into the priority queue, maintaining heap order.
PairNode< T > * clone(PairNode< T > *t) const
Internal method to clone subtree.
void reclaimMemory(PairNode< T > *t) const
Internal method to make the tree empty.
PairNode< T > * root
const PairingHeap & operator=(const PairingHeap &rhs)
Deep copy.
PairNode< T > * combineSiblings(PairNode< T > *firstSibling)
Internal method that implements two-pass merging.
void makeEmpty()
const T extractMin()
unsigned counter
RootCluster root
double c[8][4]
static gint counter
Definition box3d.cpp:39
PairNode * leftChild
PairNode * prev
PairNode * nextSibling
PairNode(const T &theElement)