diff options
| author | MenTaLguY <mental@rydia.net> | 2006-01-16 02:36:01 +0000 |
|---|---|---|
| committer | mental <mental@users.sourceforge.net> | 2006-01-16 02:36:01 +0000 |
| commit | 179fa413b047bede6e32109e2ce82437c5fb8d34 (patch) | |
| tree | a5a6ac2c1708bd02288fbd8edb2ff500ff2e0916 /src/removeoverlap/pairingheap | |
| download | inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.tar.gz inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.zip | |
moving trunk for module inkscape
(bzr r1)
Diffstat (limited to 'src/removeoverlap/pairingheap')
| -rw-r--r-- | src/removeoverlap/pairingheap/.cvsignore | 5 | ||||
| -rw-r--r-- | src/removeoverlap/pairingheap/PairingHeap.cpp | 309 | ||||
| -rw-r--r-- | src/removeoverlap/pairingheap/PairingHeap.h | 111 | ||||
| -rw-r--r-- | src/removeoverlap/pairingheap/dsexceptions.h | 9 |
4 files changed, 434 insertions, 0 deletions
diff --git a/src/removeoverlap/pairingheap/.cvsignore b/src/removeoverlap/pairingheap/.cvsignore new file mode 100644 index 000000000..e8014d011 --- /dev/null +++ b/src/removeoverlap/pairingheap/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +.deps +makefile +.dirstamp diff --git a/src/removeoverlap/pairingheap/PairingHeap.cpp b/src/removeoverlap/pairingheap/PairingHeap.cpp new file mode 100644 index 000000000..9c67f44fa --- /dev/null +++ b/src/removeoverlap/pairingheap/PairingHeap.cpp @@ -0,0 +1,309 @@ +/** + * \brief Pairing heap datastructure implementation + * + * Based on example code in "Data structures and Algorithm Analysis in C++" + * by Mark Allen Weiss, used and released under the GPL by permission + * of the author. + * + * No promises about correctness. Use at your own risk! + * + * Authors: + * Mark Allen Weiss + * Tim Dwyer <tgdwyer@gmail.com> + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#include <vector> + +#include "dsexceptions.h" +#include "PairingHeap.h" + +#ifndef PAIRING_HEAP_CPP +#define PAIRING_HEAP_CPP +using namespace std; +/** +* Construct the pairing heap. +*/ +template <class T> +PairingHeap<T>::PairingHeap( bool (*lessThan)(T &lhs, T &rhs) ) +{ + root = NULL; + counter=0; + this->lessThan=lessThan; +} + + +/** +* Copy constructor +*/ +template <class T> +PairingHeap<T>::PairingHeap( const PairingHeap<T> & rhs ) +{ + root = NULL; + counter=rhs->size(); + *this = rhs; +} + +/** +* Destroy the leftist heap. +*/ +template <class T> +PairingHeap<T>::~PairingHeap( ) +{ + makeEmpty( ); +} + +/** +* Insert item x into the priority queue, maintaining heap order. +* Return a pointer to the node containing the new item. +*/ +template <class T> +PairNode<T> * +PairingHeap<T>::insert( const T & x ) +{ + PairNode<T> *newNode = new PairNode<T>( x ); + + if( root == NULL ) + root = newNode; + else + compareAndLink( root, newNode ); + counter++; + return newNode; +} +template <class T> +int PairingHeap<T>::size() { + return counter; +} +/** +* Find the smallest item in the priority queue. +* Return the smallest item, or throw Underflow if empty. +*/ +template <class T> +const T & PairingHeap<T>::findMin( ) const +{ + if( isEmpty( ) ) + throw Underflow( ); + return root->element; +} +/** + * Remove the smallest item from the priority queue. + * Throws Underflow if empty. + */ +template <class T> +void PairingHeap<T>::deleteMin( ) +{ + if( isEmpty( ) ) + throw Underflow( ); + + PairNode<T> *oldRoot = root; + + if( root->leftChild == NULL ) + root = NULL; + else + root = combineSiblings( root->leftChild ); + counter--; + delete oldRoot; +} + +/** +* Test if the priority queue is logically empty. +* Returns true if empty, false otherwise. +*/ +template <class T> +bool PairingHeap<T>::isEmpty( ) const +{ + return root == NULL; +} + +/** +* Test if the priority queue is logically full. +* Returns false in this implementation. +*/ +template <class T> +bool PairingHeap<T>::isFull( ) const +{ + return false; +} + +/** +* Make the priority queue logically empty. +*/ +template <class T> +void PairingHeap<T>::makeEmpty( ) +{ + reclaimMemory( root ); + root = NULL; +} + +/** +* Deep copy. +*/ +template <class T> +const PairingHeap<T> & +PairingHeap<T>::operator=( const PairingHeap<T> & rhs ) +{ + if( this != &rhs ) + { + makeEmpty( ); + root = clone( rhs.root ); + } + + return *this; +} + +/** +* Internal method to make the tree empty. +* WARNING: This is prone to running out of stack space. +*/ +template <class T> +void PairingHeap<T>::reclaimMemory( PairNode<T> * t ) const +{ + if( t != NULL ) + { + reclaimMemory( t->leftChild ); + reclaimMemory( t->nextSibling ); + delete t; + } +} + +/** +* Change the value of the item stored in the pairing heap. +* Does nothing if newVal is larger than currently stored value. +* p points to a node returned by insert. +* newVal is the new value, which must be smaller +* than the currently stored value. +*/ +template <class T> +void PairingHeap<T>::decreaseKey( PairNode<T> *p, + const T & newVal ) +{ + if( p->element < newVal ) + return; // newVal cannot be bigger + 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 ); + } +} + +/** +* Internal method that is the basic operation to maintain order. +* Links first and second together to satisfy heap order. +* first is root of tree 1, which may not be NULL. +* first->nextSibling MUST be NULL on entry. +* second is root of tree 2, which may be NULL. +* first becomes the result of the tree merge. +*/ +template <class T> +void PairingHeap<T>:: +compareAndLink( PairNode<T> * & first, + PairNode<T> *second ) const +{ + if( second == NULL ) + return; + if( lessThan(second->element,first->element) ) + { + // Attach first as leftmost child of second + second->prev = first->prev; + first->prev = second; + first->nextSibling = second->leftChild; + if( first->nextSibling != NULL ) + first->nextSibling->prev = first; + second->leftChild = first; + first = second; + } + else + { + // Attach second as leftmost child of first + second->prev = first; + first->nextSibling = second->nextSibling; + if( first->nextSibling != NULL ) + first->nextSibling->prev = first; + second->nextSibling = first->leftChild; + if( second->nextSibling != NULL ) + second->nextSibling->prev = second; + first->leftChild = second; + } +} + +/** +* Internal method that implements two-pass merging. +* firstSibling the root of the conglomerate; +* assumed not NULL. +*/ +template <class T> +PairNode<T> * +PairingHeap<T>::combineSiblings( PairNode<T> *firstSibling ) const +{ + if( firstSibling->nextSibling == NULL ) + return firstSibling; + + // Allocate the array + static vector<PairNode<T> *> treeArray( 5 ); + + // Store the subtrees in an array + int numSiblings = 0; + for( ; firstSibling != NULL; numSiblings++ ) + { + if( numSiblings == (int)treeArray.size( ) ) + treeArray.resize( numSiblings * 2 ); + treeArray[ numSiblings ] = firstSibling; + firstSibling->prev->nextSibling = NULL; // break links + firstSibling = firstSibling->nextSibling; + } + if( numSiblings == (int)treeArray.size( ) ) + treeArray.resize( numSiblings + 1 ); + treeArray[ numSiblings ] = NULL; + + // Combine subtrees two at a time, going left to right + int i = 0; + for( ; i + 1 < numSiblings; i += 2 ) + compareAndLink( treeArray[ i ], treeArray[ i + 1 ] ); + + int j = i - 2; + + // j has the result of 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 ] ); + return treeArray[ 0 ]; +} + +/** +* Internal method to clone subtree. +* WARNING: This is prone to running out of stack space. +*/ +template <class T> +PairNode<T> * +PairingHeap<T>::clone( PairNode<T> * t ) const +{ + if( t == NULL ) + return NULL; + else + { + PairNode<T> *p = new PairNode<T>( t->element ); + if( ( p->leftChild = clone( t->leftChild ) ) != NULL ) + p->leftChild->prev = p; + if( ( p->nextSibling = clone( t->nextSibling ) ) != NULL ) + p->nextSibling->prev = p; + return p; + } +} + +#endif diff --git a/src/removeoverlap/pairingheap/PairingHeap.h b/src/removeoverlap/pairingheap/PairingHeap.h new file mode 100644 index 000000000..586a591a8 --- /dev/null +++ b/src/removeoverlap/pairingheap/PairingHeap.h @@ -0,0 +1,111 @@ +/** + * \brief Pairing heap datastructure implementation + * + * Based on example code in "Data structures and Algorithm Analysis in C++" + * by Mark Allen Weiss, used and released under the GPL by permission + * of the author. + * + * No promises about correctness. Use at your own risk! + * + * Authors: + * Mark Allen Weiss + * Tim Dwyer <tgdwyer@gmail.com> + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ +#ifndef PAIRING_HEAP_H_ +#define PAIRING_HEAP_H_ +#include <stdlib.h> +// Pairing heap class +// +// CONSTRUCTION: with no parameters +// +// ******************PUBLIC OPERATIONS********************* +// PairNode & insert( x ) --> Insert x +// deleteMin( minItem ) --> Remove (and optionally return) smallest item +// T findMin( ) --> Return smallest item +// bool isEmpty( ) --> Return true if empty; else false +// bool isFull( ) --> Return true if empty; else false +// void makeEmpty( ) --> Remove all items +// void decreaseKey( PairNode p, newVal ) +// --> Decrease value in node p +// ******************ERRORS******************************** +// Throws Underflow as warranted + + +// Node and forward declaration because g++ does +// not understand nested classes. +template <class T> +class PairingHeap; + +template <class T> +class PairNode +{ + T element; + PairNode *leftChild; + PairNode *nextSibling; + PairNode *prev; + + PairNode( const T & theElement ) : element( theElement ), + leftChild(NULL), nextSibling(NULL), prev(NULL) { } + friend class PairingHeap<T>; +}; + +template <class T> +class Comparator +{ +public: + virtual bool isLessThan(const T &lhs, const T &rhs) const = 0; +}; + +template <class T> +class PairingHeap +{ +public: + PairingHeap( bool (*lessThan)(T &lhs, T &rhs) ); + PairingHeap( const PairingHeap & rhs ); + ~PairingHeap( ); + + bool isEmpty( ) const; + bool isFull( ) const; + int size(); + + PairNode<T> *insert( const T & x ); + const T & findMin( ) const; + void deleteMin( ); + void makeEmpty( ); + void decreaseKey( PairNode<T> *p, const T & newVal ); + void merge( PairingHeap<T> *rhs ) + { + PairNode<T> *broot=rhs->getRoot(); + if (root == NULL) { + if(broot != NULL) { + root = broot; + } + } else { + compareAndLink(root, broot); + } + counter+=rhs->size(); + } + + const PairingHeap & operator=( const PairingHeap & rhs ); +protected: + PairNode<T> * getRoot() { + PairNode<T> *r=root; + root=NULL; + return r; + } +private: + PairNode<T> *root; + bool (*lessThan)(T &lhs, T &rhs); + int counter; + void reclaimMemory( PairNode<T> *t ) const; + void compareAndLink( PairNode<T> * & first, PairNode<T> *second ) const; + PairNode<T> * combineSiblings( PairNode<T> *firstSibling ) const; + PairNode<T> * clone( PairNode<T> * t ) const; +}; + +#include "PairingHeap.cpp" +#endif diff --git a/src/removeoverlap/pairingheap/dsexceptions.h b/src/removeoverlap/pairingheap/dsexceptions.h new file mode 100644 index 000000000..bef2c78c5 --- /dev/null +++ b/src/removeoverlap/pairingheap/dsexceptions.h @@ -0,0 +1,9 @@ +#ifndef DSEXCEPTIONS_H_ +#define DSEXCEPTIONS_H_ + +class Underflow { }; +class Overflow { }; +class OutOfMemory { }; +class BadIterator { }; + +#endif |
