//斐波那契堆. #include <iostream> #include <type_traits> #include <cmath>
template<typename T> class FibNode{ public: T key;//堆内数据。如果key是一个class需要重载operator<(). int degree;//维度. 当前节点中孩子链表中孩子的数目. FibNode<T>* left; FibNode<T>* right; FibNode<T>* parent; FibNode<T>* child; bool mark; //记录该节点是否删除了第一个孩子. 删除了为true,没删除为false; FibNode(const T& k); };
template<typename T> FibNode<T>::FibNode(const T& k) :key(k), degree(0), left(this), //由于fibonacci堆的特点是所有节点串起来(从左到右 从右到左)是一个双向的链表所以当创建一个新节点的时候也就是说 right(this), //值由一个节点的时候那么该节点的的父节点(parent)和孩子节点(child)都是可以为空的。但是由于是一个双向链表所以他的左右节点都是他自己。 parent(nullptr), child(nullptr), mark(false) { //节点构造函数。 }
template<typename U> class FibHeap{ private: int nodeNumber;//堆内的节点总数. int maxDegree;//记录堆内拥有最多孩子节点的节点的维度. FibNode<U>* minNode;//关键字最小的节点.(也就是FibHeap的头节点.) void addNode(FibNode<U>* node, FibNode<U>* root);//这里的root一般就是minNode. void combine(FibNode<U>* a, FibNode<U>* b); void removeMin(FibNode<U>* deletedNode); void consolidate(); FibNode<U>* getMin(); void link(FinNode<U>* a, FibNode<U>* b); template<typename Ty, class=typename std::enable_if< std::is_same<U, Ty>::value, void >::type> void cut(FibNode<Ty>* cutedNode, FibNode<Ty>* parent); template<typename Ty, class=typename std::enable_if< std::is_same<U, Ty>::value, void >::type> void cascadingCut(FibNode<Ty>* node); public: FibHeap(); ~FibHeap(); template<typename Ty, class=typename std::enable_if< std::is_same<U, Ty>::value, void >::type> void insert(const Ty& k); template<typename X, class=typename std::enable_if< std::is_same<U, X>::value, void >::type> void unionHeap(FibHeap<X>* other); FibNode<U>* extractMin(); void renewDegree(FibNode<U>* parent, const int& tempDegree); template<typename Ty, class=typename std::enable_if< std::is_same<U, Ty>::value, void >::type> void decrease(FibNode<Ty>* decNode, const Ty& k); }; template<typename U> FibHeap<U>::FibHeap() :maxNumber(0), maxDegree(0), minDegree(nullptr) { std::cout<<"success"<<std::endl; }
1,insert操作:
template<typename U> template<typename Ty, class> void FibHeap<U>::insert(const Ty& k) { FibNode<Ty>* tempNode=new FibNode<Ty>(k); if(tempNode == nullptr){ return; } if(this->nodeNumber == 0){ this->minNode=tempNode; }else{ this->addNode(tempNode, this->minNode); if(node->key < (this->minNode)->key){ //对比被插入节点的key值是否小于heap内key最小的点,如果小于那么另heap等于当前被插入的节点. minNode=node; } } ++nodeNumber;//节点增加一个此处加1. }
template<typename U> void FibHeap<U>::addNode(FibNode<U>* node, FibNode<U>* root) { node->left = root->left; //另被插入节点的左节点等于根节点右节点. (root->left)->right = node; //另minNode节点的左节点的右节点等于将要插入的节点. node->right = root; root->left = node; }