dheap.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * GCache                                                                    *
00003 * Author: Federico Ponchio                                                  *
00004 *                                                                           *
00005 * Copyright(C) 2011                                                         *
00006 * Visual Computing Lab                                                      *
00007 * ISTI - Italian National Research Council                                  *
00008 *                                                                           *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *   
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 
00024 #ifndef DD_HEAP_H
00025 #define DD_HEAP_H
00026 
00041 #include <assert.h>
00042 #include <vector>
00043 
00044 
00045 template <class T>
00046 class DHeap: public std::vector<T> {
00047 public:
00048 
00049   void push(const T& elt) {
00050     this->push_back(elt);
00051     bubbleUp(this->size()-1);
00052   }
00053 
00054   T &min() { return this->front(); } //root is smallest element
00055 
00056   T popMin() {
00057     T elt = this->front();
00058     //move the last element to the root and
00059     this->front() = this->back();
00060     this->pop_back();
00061     //enforce minmax heap property
00062     trickleDownMin(0);
00063     return elt;
00064   }
00065 
00066   //max is second element
00067   T &max() {
00068     if(this->size() == 1) return at(0);
00069     return at(1);
00070   }
00071 
00072   T popMax() {
00073     int p = 1;
00074     if(this->size() == 1) p = 0;
00075     T elt = at(p);
00076     //max is replaced with last item.
00077     at(p) = this->back();
00078     this->pop_back();
00079     trickleDownMax(p); //enforce minmax heap property
00080     return elt;
00081   }
00082 
00083   //just reinsert all elements
00084   void rebuild() { 
00085     for(unsigned int i = 0; i < this->size(); i++)
00086       bubbleUp(i);
00087   }
00088 
00089 protected:
00090   T &at(int n) { return std::vector<T>::at(n); }
00091 
00092   int isMax(int e) const { return e & 1; }
00093   int parentMin(int i) const { return (((i+2)>>2)<<1) - 2; }
00094   int parentMax(int i) const { return (((i+2)>>2)<<1) - 1; }
00095   int leftChildMin(int i) const { return (((i+2)>>1)<<2) -2; }
00096   int leftChildMax(int i) const { return (((i+2)>>1)<<2) -1; }
00097 
00098   void swap(int a, int b) { T tmp = at(a); at(a) = at(b); at(b) = tmp; }
00099 
00100   //returns smallest elemennt of children intervals (or self if no children)
00101   int smallestChild(int i) {
00102     int l = leftChildMin(i);
00103     if(l >= this->size()) return i; //no children, return self
00104 
00105     int r = l+2; //right child
00106     if(r < this->size() && at(r) < at(l))
00107       return r;
00108     return l;
00109   }
00110   //return biggest children or self if no children
00111   int greatestChild(int i) {
00112     int l = leftChildMax(i);
00113     if(l >= this->size()) return i; //no children, return self
00114 
00115     int r = l+2; //right child
00116     if(r < this->size() && at(r) > at(l))
00117       return r;
00118     return l;
00119   }
00120 
00121   //all stuff involving swaps could be optimized perofming circular swaps
00122   // but you mantain the code after :)
00123   void trickleDownMin(int i) {
00124     while(1) {
00125 
00126       //find smallest child
00127       unsigned int m = leftChildMin(i);
00128       if(m >= this->size()) break;
00129       unsigned int r = m+2;
00130       if(r < this->size() && at(r) < at(m))
00131         m = r;
00132 
00133       if(at(m) < at(i)) { //if child is smaller swap
00134         swap(i, m);
00135         i = m; //check swapped children
00136       } else //no swap? finish
00137         break;
00138 
00139       m = i+1;       //enforce order in interval
00140       if(m >= this->size()) break;
00141       if(at(m) < at(i))
00142         swap(i, m);
00143     }
00144   }
00145 
00146   void trickleDownMax(int i) {
00147     while(1) {
00148 
00149       //find greatest child
00150       unsigned int m = leftChildMax(i);
00151       if(m >= this->size()) break;
00152       unsigned int r = m+2;
00153       if(r < this->size() && at(r) > at(m))
00154         m = r;
00155 
00156       if(at(m) > at(i)) {
00157         swap(i, m);
00158         i = m;
00159       } else
00160         break;
00161 
00162       m = i-1;       //enforce order in interval
00163       if(m >= this->size()) break;
00164       if(at(m) > at(i)) {
00165         swap(i, m);
00166       }
00167     }
00168   }
00169 
00170   void bubbleUpMin(int i) {
00171     while(1) {
00172       int m = parentMin(i);
00173       if(m < 0) break;
00174       if(at(m) > at(i)) {
00175         swap(i, m);
00176         i = m;
00177       } else
00178         break;
00179     }
00180   }
00181 
00182   void bubbleUpMax(int i) {
00183     while(1) {
00184       int m = parentMax(i);
00185       if(m < 0) break;
00186       if(at(m) < at(i)) {
00187         swap(i, m);
00188         i = m;
00189       } else
00190         break;
00191     }
00192   }
00193 
00194   void bubbleUp(int i) {
00195     if(isMax(i)) {
00196       int m = i-1;
00197       if(at(m) > at(i)) {
00198         swap(i, m);
00199         bubbleUpMin(m);
00200       } else
00201         bubbleUpMax(i);
00202     } else {
00203       int m = parentMax(i);
00204       if(m < 0) return;
00205       if(at(m) < at(i)) {
00206         swap(i, m);
00207         bubbleUpMax(m);
00208       } else
00209         bubbleUpMin(i);//just reinsert all elements, (no push back necessary, of course
00210     }
00211   }
00212   /* DEBUG */
00213  public:
00215   bool isHeap() { //checks everything is in order
00216     int s = this->size();
00217     for(int i = 0; i < s; i += 2) {
00218       if(i+1 < s && at(i) > at(i+1)) return false;
00219       int l = leftChildMin(i);
00220       if(l < s && at(i) > at(l)) return false;
00221       int r = l + 2;
00222       if(r < s && at(i) > at(r)) return false;
00223     }
00224     for(int i = 1; i < s; i += 2) {
00225       int l = leftChildMax(i);
00226       if(l < s && at(i) < at(l)) return false;
00227       int r = l + 2;
00228       if(r < s && at(i) < at(r)) return false;
00229     }
00230     return true;
00231   }
00232 };
00233 
00236 template <class T>
00237 class PtrDHeap {
00238  private:
00239   class Item {
00240     public:
00241     T *value;
00242     Item(T *val): value(val) {}
00243     bool operator<(const Item &i) const { return *value < *i.value; }
00244     bool operator>(const Item &i) const { return *value > *i.value; }
00245   };
00246   DHeap<Item> heap;
00247 
00248  public:
00249   T *push(T *t) {
00250     Item i(t);
00251     heap.push(i);
00252     return i.value;
00253   }
00254   void push_back(T *t) {
00255     heap.push_back(Item(t));
00256   }
00257   int size() { return heap.size(); }
00258   void resize(int n) { assert(n <= (int)heap.size()); return heap.resize(n, Item(NULL)); }
00259   void clear() { heap.clear(); }
00260   T &min() { Item &i = heap.min(); return *i.value; }
00261   T *popMin() { Item i = heap.popMin(); return i.value; }
00262 
00263   T &max() { Item &i = heap.max(); return *i.value; }
00264   T *popMax() { Item i = heap.popMax(); return i.value; }
00265 
00266   void rebuild() { heap.rebuild(); }
00267   T &operator[](int i) {
00268     return *(heap[i].value);
00269   }
00270   Item &at(int i) { return heap[i]; }
00271   bool isHeap() { return heap.isHeap(); }
00272 };
00273 
00274 #endif


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:30:31