makrusak

binominal_heap

Dec 11th, 2013
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.38 KB | None | 0 0
  1. #include <cstdlib>
  2. #include <algorithm>
  3.  
  4. template< typename T, typename Cmp>
  5. class Heap {
  6.  
  7.   private:
  8.     template <class U, class Z> friend class HeapTest;
  9.  
  10.     class Vertex {
  11.       private:
  12.         friend class Heap;
  13.         template <class U, class Z> friend class HeapTest;
  14.  
  15.         Vertex(T val):key(val), parent(NULL), child(NULL), sibling(NULL), degree(0) { }
  16.         T key;
  17.         Vertex *parent, *child, *sibling;
  18.         unsigned short degree;
  19.     };
  20.    
  21.   public:
  22.     /*  
  23.     class Reference {
  24.       friend class Heap;
  25.      
  26.       public:
  27.         Reference() {}
  28.      
  29.       private:
  30.         explicit Reference(Vertex *get):ref(get) {}
  31.         Vertex **ref;
  32.     };
  33.     */
  34.     /* Debug
  35.     void puts_list(Vertex *head) {
  36.       for (;head;head = head->sibling) std::cout << head->degree << " ";
  37.       std::cout << "\n";
  38.     }
  39.  
  40.     bool check_list(Vertex *head) {
  41.       if (!head) return true;
  42.       Vertex* cur = head;
  43.       bool ok = true;
  44.       for (;cur->sibling;cur = cur->sibling) {
  45.         if (cur->degree > cur->sibling->degree) ok = false;
  46.       }
  47.       return ok;
  48.     }
  49.  
  50.     void print_tree() {
  51.       print(head);
  52.     }
  53.  
  54.     void print(Vertex* head) {
  55.       if (!head) return;
  56.       std::cout << "Val " << head->key << "\n";
  57.       print(head->child);
  58.       print(head->sibling);
  59.     }
  60.     */
  61.  
  62.     void merge(Heap<T, Cmp> &other) {
  63.       if (other.head == NULL) return;
  64.  
  65.       //create fictive vertex
  66.       Vertex* new_head = new Vertex(-1);
  67.      
  68.       //merge lists of vertexes
  69.       Vertex *curh = new_head, *curh1 = head, *curh2 = other.head;
  70.       while (curh1 || curh2) {
  71.         if (!curh2 || (curh1 && curh1->degree < curh2->degree ) ) connect_and_move(curh, curh1);
  72.         else connect_and_move(curh, curh2);
  73.       }
  74.  
  75.       //reduce vertexes of equal size
  76.       curh = new_head;
  77.       while (curh->sibling->sibling) {
  78.         Vertex *fir = curh->sibling;
  79.         Vertex *sec = fir->sibling;
  80.         Vertex* next = sec->sibling;
  81.         if (fir->degree == sec->degree && (!next || sec->degree!=next->degree)) {
  82.           if (!cmp(fir->key, sec->key)) std::swap(fir, sec);
  83.           sec->sibling = fir->child;
  84.           fir->child = sec;
  85.           sec->parent = fir;
  86.           curh->sibling = fir;
  87.           fir->sibling = next;
  88.           fir->degree++;
  89.         }
  90.         else {
  91.           curh = curh->sibling;
  92.         }
  93.       }
  94.       head = new_head->sibling;
  95.       delete new_head;
  96.     }
  97.  
  98.     /*  Reference */ void insert(T val) {
  99.       Heap<T, Cmp> nw = Heap(val);
  100.       //Reference result(nw.head);
  101.       merge(nw);
  102.       //return result;
  103.     }
  104.  
  105.     void extract_min() {
  106.       //find vertex with min key and save its degree
  107.       T minkey = head->key;
  108.       unsigned short minkeydeg = head->degree;
  109.       for( Vertex* cur = head; cur; cur = cur->sibling ) {
  110.         if (cmp(cur->key, minkey)) {
  111.           minkey = cur->key;
  112.           minkeydeg = cur->degree;
  113.         }
  114.       }
  115.  
  116.       //delete min vertex
  117.       Vertex* del;
  118.       if (head->degree==minkeydeg) {
  119.         del = head;
  120.         head = head->sibling;
  121.       }
  122.       else {
  123.         Vertex* cur = head;
  124.         while (cur->sibling->degree != minkeydeg) cur = cur->sibling;
  125.         del = cur->sibling;
  126.         cur->sibling = del->sibling;
  127.       }
  128.       //create heap of childs and merge
  129.       Heap<T, Cmp> heap = Heap();
  130.       Vertex* fir = del->child;
  131.       delete del;
  132.       while (fir) {
  133.         Vertex* next = fir->sibling;
  134.         fir->sibling = heap.head;
  135.         fir->parent = NULL;
  136.         heap.head = fir;
  137.         fir = next;
  138.       }
  139.       merge(heap);
  140.     }
  141.  
  142.     bool empty() {
  143.       return (head==NULL);
  144.     }
  145.  
  146.  
  147.  
  148.     T find_min() {
  149.       Vertex* cur = head;
  150.       T min = cur->key;
  151.       while (cur) {
  152.         if (cmp(cur->key, min)) min = cur->key;
  153.         cur = cur->sibling;
  154.       }
  155.       return min;
  156.     }
  157.  
  158.  
  159.     Heap(T val, Cmp comp = Cmp()) {
  160.       head = new Vertex(val);
  161.       cmp = comp;
  162.     }
  163.  
  164.     Heap(Cmp comp = Cmp()) {
  165.       head = NULL;
  166.       cmp = comp;
  167.     }
  168.  
  169.   private:
  170.     inline void connect_and_move(Vertex* &head, Vertex* &to) {
  171.       head->sibling = to;
  172.       to = to->sibling;
  173.       head = head->sibling;
  174.     }
  175.    
  176.     Vertex* head;
  177.     Cmp cmp;
  178. };
  179.  
  180. template< typename T, typename Cmp = std::less<T> >
  181. Heap<T, Cmp> MakeHeap(Cmp cmp = Cmp()) {
  182.   return Heap<T, Cmp>(cmp);
  183. }
Advertisement
Add Comment
Please, Sign In to add comment