Advertisement
igoryanchik

FibonacciHeap

Oct 16th, 2023 (edited)
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.19 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <cmath>
  4. using namespace std;
  5.  
  6. template <class T>
  7. class Node
  8. {
  9. private:
  10.     T data;
  11.     Node<T>* left;
  12.     Node<T>* right;
  13.     Node<T>* parent;
  14.     Node<T>* child;
  15.     bool marked;
  16.     int degree;
  17.  
  18.     Node<T>()
  19.         : data(T())
  20.         , left(this)
  21.         , right(this)
  22.         , parent(nullptr)
  23.         , child(nullptr)
  24.         , marked(false)
  25.         , degree(0)
  26.     {}
  27.  
  28.     Node<T>(const T& n)
  29.         : data(n)
  30.         , left(this)
  31.         , right(this)
  32.         , parent(nullptr)
  33.         , child(nullptr)
  34.         , marked(false)
  35.         , degree(0)
  36.     {}
  37.  
  38.     T getData() const
  39.     {
  40.         return data;
  41.     }
  42.  
  43.     void setData(const T& n)
  44.     {
  45.         data = n;
  46.     }
  47.  
  48.     ~Node<T>()
  49.     {
  50.         delete left;
  51.         delete right;
  52.         delete parent;
  53.         delete child;
  54.         left = right = parent = child = nullptr;
  55.     }
  56.  
  57.     template <class T>
  58.     friend class FibonacciHeap;
  59.  
  60. };
  61.  
  62. template <class T>
  63. class FibonacciHeap
  64. {
  65. private:
  66.  
  67.     Node<T>* root;
  68.  
  69.     int size;
  70.  
  71.  
  72.     void inserting(Node<T>* _root, Node<T>* x)
  73.     {
  74.         x->left = _root;
  75.         x->right = _root->right;
  76.         _root->right->left = x;
  77.         _root->right = x;
  78.     }
  79.  
  80.     void take_out(Node<T>* x)
  81.     {
  82.         x->left->right = x->right;
  83.         x->right->left = x->left;
  84.     }
  85.  
  86.     void link(Node<T>* parent, Node<T>* child)
  87.     {
  88.  
  89.         if (!parent || !child) throw "Nullptr";
  90.  
  91.         child->parent = parent;
  92.         take_out(child);
  93.  
  94.         if (!parent->child)
  95.         {
  96.             parent->child = child;
  97.             child->left = child;
  98.             child->right = child;
  99.         }
  100.         else
  101.             inserting(parent->child, child);
  102.  
  103.         parent->degree++;
  104.         parent->marked = false;
  105.  
  106.     }
  107.  
  108.     void consolidate()
  109.     {
  110.         vector<Node<T>*> degrees(int(log2(size)) + 1, nullptr);
  111.         vector<Node<T>*> elements;
  112.  
  113.  
  114.         Node<T>* cur = root;
  115.         do
  116.         {
  117.             elements.push_back(cur);
  118.             cur = cur->right;
  119.         } while (cur != root);
  120.  
  121.  
  122.         for (auto it : elements)
  123.         {
  124.             int curDegree = it->degree;
  125.  
  126.             while (degrees[curDegree])
  127.             {
  128.                 Node<T>* buff = degrees[curDegree];
  129.  
  130.                 if (it->data > buff->data)
  131.                     swap(it, buff);
  132.  
  133.                 link(it, buff);
  134.                 degrees[curDegree] = nullptr;
  135.                 curDegree++;
  136.             }
  137.             degrees[curDegree] = it;
  138.         }
  139.  
  140.         root = nullptr;
  141.         for (auto it : degrees)
  142.         {
  143.             if (it)
  144.             {
  145.                 if (!root) root = it;
  146.  
  147.                 take_out(it);
  148.                 inserting(root, it);
  149.  
  150.                 if (root->data > it->data) root = it;
  151.  
  152.             }
  153.         }
  154.     }
  155.  
  156.     void cut(Node<T>* parent, Node<T>* child)
  157.     {
  158.         take_out(child);
  159.  
  160.         if (parent->child == child)
  161.         {
  162.             if (child->right == child)
  163.                 parent->child = nullptr;
  164.             else
  165.                 parent->child = child->right;
  166.         }
  167.  
  168.         child->parent = nullptr;
  169.         child->marked = false;
  170.         inserting(root, child);
  171.  
  172.         if (child->data < root->data)
  173.             root = child;
  174.  
  175.         parent->degree--;
  176.     }
  177.  
  178.     void cascadingCut(Node<T>* x)
  179.     {
  180.         if (x->parent != nullptr)
  181.         {
  182.             if (!x->marked)
  183.                 x->marked = true;
  184.             else
  185.             {
  186.                 cut(x->parent, x);
  187.                 cascadingCut(x->parent);
  188.             }
  189.         }
  190.  
  191.  
  192.     }
  193.  
  194.  
  195. public:
  196.  
  197.     FibonacciHeap()
  198.         : root(nullptr)
  199.         , size(0)
  200.     {}
  201.  
  202.     T getMin() const
  203.     {
  204.         return root->data;
  205.     }
  206.  
  207.     int count() const
  208.     {
  209.         return size;
  210.     }
  211.  
  212.     void add(const T& elem)
  213.     {
  214.         Node<T>* newNode = new Node<T>(elem);
  215.  
  216.         if (!root)
  217.             root = newNode;
  218.         else
  219.         {
  220.             inserting(root, newNode);
  221.  
  222.             if (root->data > newNode->data)
  223.                 root = newNode;
  224.         }
  225.         size++;
  226.     }
  227.  
  228.  
  229.     FibonacciHeap<T> merge(FibonacciHeap<T>& H)
  230.     {
  231.         if (!H.root) throw "Nullptr";
  232.         else if (!root)
  233.             root = H.root;
  234.         else
  235.         {
  236.             inserting(root, H.root);
  237.             root = (root->data < H.root->data ? root : H.root);
  238.         }
  239.  
  240.         size += H.size;
  241.         H.size = 0;
  242.         H.root = nullptr;
  243.  
  244.         return *this;
  245.     }
  246.  
  247.     Node<T>* remove_min()
  248.     {
  249.         if (!root) throw "Heap is empty";
  250.  
  251.         if (root->child)
  252.         {
  253.             Node<T>* cur = root->child;
  254.  
  255.             do
  256.             {
  257.                 cur = cur->right;
  258.                 inserting(root, cur);
  259.                 cur->parent = nullptr;
  260.  
  261.             } while (cur != root->child);
  262.         }
  263.  
  264.         take_out(root);
  265.  
  266.         if (root == root->right)
  267.             root = nullptr;
  268.         else
  269.         {
  270.             root = root->right;
  271.             consolidate();
  272.         }
  273.         return root;
  274.     }
  275.  
  276.  
  277.     void decrease_key(Node<T>* x, const T& k)
  278.     {
  279.         if (k >= x->data)
  280.         {
  281.             cout << "New data is greater then current\n";
  282.             return;
  283.         }
  284.  
  285.         x->data = k;
  286.         if (x->parent && x->data < x->parent->data)
  287.         {
  288.             cur(x->parent, x);
  289.             cascadingCut(x->parent);
  290.         }
  291.     }
  292.  
  293.  void destroyNodes(Node<T>* node)
  294.    {
  295.         if (node)
  296.        {
  297.             Node<T>* cur = node;
  298.             do
  299.            {
  300.                 Node<T>* next = cur->right;
  301.                 destroyNodes(cur->child);
  302.                 delete cur;
  303.                 cur = next;
  304.             } while (cur != node);
  305.         }
  306.     }
  307.  
  308. ~FibonacciHeap()
  309. {
  310.    destroyNodes(root);
  311. }
  312.  
  313. };
  314.  
  315. int main()
  316. {
  317.     FibonacciHeap<int> A;
  318.  
  319.     A.add(10);
  320.     A.add(11);
  321.     A.add(15);
  322.     A.add(-1);
  323.  
  324.     cout << "Minimum: " << A.getMin() << '\n';
  325.     cout << "Size of Heap: " << A.count() << '\n';
  326.  
  327.     cout << "\nRemove min:\n";
  328.     A.remove_min();
  329.     cout << "Current min: " << A.getMin() << '\n';
  330.  
  331.     cout << "\nMerge of Heaps:\n";
  332.  
  333.     FibonacciHeap<int> B;
  334.     B.add(40);
  335.     B.add(-199);
  336.     B.add(14);
  337.     B.add(0);
  338.  
  339.     cout << "Heap B min: " << B.getMin() << '\n';
  340.     cout << "Heap A min: " << A.getMin() << '\n';
  341.     cout << "Connect Heap A and Heap B:\n";
  342.     A.merge(B);
  343.     cout << "Current min: " << A.getMin() << '\n';
  344.  
  345.  
  346.     cout << "\nDecrease min key\n";
  347.    
  348.  
  349.  
  350.     return 0;
  351. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement