Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <assert.h>
- using namespace std;
- #define debug(x) cout<<"Area "<<x<<" maybe safe\n";
- template< typename T1 = int, typename T2 = int >
- struct Data{
- T1 first;
- T2 second;
- Data(){}
- Data(T1 first, T2 second) : first(first), second(second) {}
- friend ostream &operator<<(ostream &os, const Data &data) {
- os << "(" << data.first << ", " << data.second<<")";
- return os;
- }
- bool operator==(const Data &rhs) const {
- return first == rhs.first &&
- second == rhs.second;
- }
- bool operator!=(const Data &rhs) const {
- return !(rhs == *this);
- }
- bool operator <(const Data &rhs) const {
- return first < rhs.first;
- }
- bool operator <=(const Data &rhs) const {
- return first <= rhs.first;
- }
- bool operator >(const Data &rhs) const {
- return first > rhs.second;
- }
- bool operator >=(const Data &rhs) const {
- return first >= rhs.first;
- }
- };
- //____________________________
- template < typename T >
- struct ListNode{
- private:
- T ListData;
- ListNode *leftNode, *rightNode;
- public:
- explicit ListNode(T data) : ListData(data) {
- leftNode = rightNode = nullptr;
- }
- T getListData() const {
- return ListData;
- }
- void setListData(T data) {
- ListNode::ListData = data;
- }
- ListNode *getLeftNode() const {
- return leftNode;
- }
- void setLeftNode(ListNode *leftNode) {
- ListNode::leftNode = leftNode;
- }
- ListNode *getRightNode() const {
- return rightNode;
- }
- void setRightNode(ListNode *rightNode) {
- ListNode::rightNode = rightNode;
- }
- virtual ~ListNode() {
- this->leftNode = this->rightNode = nullptr;
- }
- } ;
- template < typename T >
- struct LinkedList{
- private:
- ListNode<T> *headNode, *tailNode;
- unsigned int listSize;
- public:
- LinkedList(){
- headNode = tailNode = nullptr;
- listSize = 0;
- }
- ListNode<T> *getHeadNode() const {
- return headNode;
- }
- void setHeadNode(ListNode<T> *headNode) {
- LinkedList::headNode = headNode;
- }
- ListNode<T> *getTailNode() const {
- return tailNode;
- }
- void setTailNode(ListNode<T> *tailNode) {
- LinkedList::tailNode = tailNode;
- }
- unsigned int getListSize() const {
- return listSize;
- }
- void setListSize(unsigned int listSize) {
- LinkedList::listSize = listSize;
- }
- void pushFront(T newData){
- ListNode<T> *newNode = new ListNode<T>(newData);
- if(!headNode){
- headNode = tailNode = newNode;
- }
- else{
- newNode->setRightNode(this->headNode);
- this->headNode->setLeftNode(newNode);
- this->headNode = newNode;
- }
- this->listSize++;
- }
- void pushBack(T newData){
- ListNode<T> *newNode = new ListNode<T>(newData);
- if(!tailNode){
- headNode = tailNode = newNode;
- }
- else{
- newNode->setLeftNode(this->tailNode);
- this->tailNode->setRightNode(newNode);
- this->tailNode = newNode;
- }
- this->listSize++;
- }
- T frontVal(){
- assert(this->listSize!=0);
- return this->headNode->getListData();
- }
- T backVal(){
- assert(this->listSize!=0);
- return this->tailNode->getListData();
- }
- void popFront(){
- if(listSize != 0){
- if(headNode == tailNode){
- delete headNode;
- headNode = tailNode = nullptr;
- }
- else{
- ListNode<T> *temp = headNode->getRightNode();
- temp->setLeftNode(nullptr);
- delete headNode;
- headNode = temp;
- }
- listSize--;
- }
- }
- void popBack(){
- if(listSize != 0){
- if(headNode == tailNode){
- delete tailNode;
- headNode = tailNode = nullptr;
- }
- else{
- ListNode<T> *temp = tailNode->getLeftNode();
- temp->setRightNode(nullptr);
- delete tailNode;
- tailNode = temp;
- }
- listSize--;
- }
- }
- void eraseAt(ListNode<T> *listNode){
- if(listNode == nullptr)return;
- if(listNode == headNode)popFront();
- else if(listNode == tailNode)popBack();
- else{
- listNode->getLeftNode()->setRightNode(listNode->getRightNode());
- listNode->getRightNode()->setLeftNode(listNode->getLeftNode());
- delete listNode;
- listSize--;
- }
- }
- bool isEmpty(){
- return this->listSize == 0;
- }
- T getValAt(ListNode<T> *listNode){
- assert(listNode != nullptr);
- return listNode->getData();
- }
- void showList(){
- cout<<"List size: "<<getListSize()<<endl;
- ListNode<T> *temp = headNode;
- while(temp){
- cout<<temp->getListData()<<" ";
- temp = temp->getRightNode();
- }
- cout<<endl;
- }
- virtual ~LinkedList() {
- /*ListNode<T> *temp;
- while(headNode){
- temp = headNode;
- headNode = headNode->getRightNode();
- delete temp;
- }
- temp = headNode = tailNode = nullptr;
- listSize = 0;*/
- }
- };
- //__________________________
- template < typename T >
- struct TreeNode{
- T nodeValue;
- int degree, level;
- TreeNode *leftChild, *parent, *rightSibling;
- TreeNode(T nodeValue) : nodeValue(nodeValue) {
- this->degree = 0, this->level = 0;
- leftChild = rightSibling = parent = nullptr;
- }
- friend TreeNode<T>* mergeBinomialTrees(TreeNode<T> *big, TreeNode<T> *small) {
- if(big->nodeValue < small->nodeValue){
- small->parent = big;
- small->rightSibling = big->leftChild;
- big->leftChild = small;
- big->degree++;
- return big;
- }
- else{
- big->parent = small;
- big->rightSibling = small->leftChild;
- small->leftChild = big;
- small->degree++;
- return small;
- }
- }
- };
- template < typename T >
- LinkedList< TreeNode<T>* > unionLists(LinkedList< TreeNode<T>* > list1, LinkedList< TreeNode<T>* > list2){
- LinkedList< TreeNode<T>* > newList;
- ListNode< TreeNode<T>* > *iterator_1, *iterator_2;
- iterator_1 = list1.getHeadNode(), iterator_2 = list2.getHeadNode();
- while(iterator_1 || iterator_2){
- if(iterator_1 && iterator_2){
- if(iterator_1->getListData()->degree <= iterator_2->getListData()->degree){
- newList.pushBack(iterator_1->getListData());
- iterator_1 = iterator_1->getRightNode();
- }
- else{
- newList.pushBack(iterator_2->getListData());
- iterator_2 = iterator_2->getRightNode();
- }
- }
- else if(iterator_1){
- newList.pushBack(iterator_1->getListData());
- iterator_1 = iterator_1->getRightNode();
- }
- else{
- newList.pushBack(iterator_2->getListData());
- iterator_2 = iterator_2->getRightNode();
- }
- }
- return newList;
- }
- template < typename T >
- class Binomial_Heap
- {
- unsigned int nodeCounter, treeCounter;
- LinkedList< TreeNode<T>* > innerList;
- unsigned int countOnes(unsigned int n) {
- unsigned int res = 0;
- while(n && ++res) n -= n&(-n);
- return res;
- }
- void heapify(LinkedList< TreeNode<T>* > list){
- innerList = list;
- if(list.getListSize() <= 1){
- return;
- }
- ListNode< TreeNode<T>* > *iterator_1, *iterator_2, *iterator_3;
- iterator_1 = iterator_2 = iterator_3 = list.getHeadNode();
- if(list.getListSize() == 2){
- iterator_2 = iterator_2->getRightNode();
- iterator_3 = nullptr;
- }
- else{
- iterator_2 = iterator_2->getRightNode();
- iterator_3 = iterator_2;
- iterator_3 = iterator_3->getRightNode();
- }
- while(iterator_1){
- if(iterator_2 == nullptr){
- iterator_1 = iterator_1->getRightNode();
- }
- else if(iterator_1->getListData()->degree < iterator_2->getListData()->degree){
- iterator_1 = iterator_1->getRightNode();
- iterator_2 = iterator_2->getRightNode();
- if(iterator_3)
- iterator_3 = iterator_3->getRightNode();
- }
- else if(iterator_3 &&
- iterator_1->getListData()->degree == iterator_2->getListData()->degree &&
- iterator_2->getListData()->degree == iterator_3->getListData()->degree) {
- iterator_1 = iterator_1->getRightNode();
- iterator_2 = iterator_2->getRightNode();
- iterator_3 = iterator_3->getRightNode();
- }
- else if(iterator_1->getListData()->degree == iterator_2->getListData()->degree){
- if(iterator_1->getListData()->nodeValue < iterator_2->getListData()->nodeValue){
- //swap linked list consecutive nodes
- TreeNode<T>* temp = iterator_1->getListData();
- iterator_1->setListData(iterator_2->getListData());
- iterator_2->setListData(temp);
- }
- iterator_1->setListData( mergeBinomialTrees(iterator_1->getListData(), iterator_2->getListData()) );
- ListNode< TreeNode<T>* > *iter = iterator_2->getRightNode();
- list.eraseAt(iterator_2);
- iterator_2 = iter;
- if(iterator_3 != nullptr){
- iterator_3 = iterator_3->getRightNode();
- }
- }
- }
- }
- void insertATreeInHeap(TreeNode<T>* treeNode){
- LinkedList< TreeNode<T>* > temp;
- temp.pushBack(treeNode);
- heapify(unionLists(this->innerList, temp));
- }
- TreeNode<T> *getMinNodePtr(){
- LinkedList < TreeNode<T>* > _heap = innerList;
- ListNode< TreeNode<T>* > *iterator_1 = _heap.getHeadNode();
- TreeNode<T>* temp = iterator_1->getListData();
- while(iterator_1){
- if(iterator_1->getListData()->nodeValue < temp->nodeValue){
- temp = iterator_1->getListData();
- }
- iterator_1 = iterator_1->getRightNode();
- }
- return temp;
- }
- T getValueAt(TreeNode<T>* treeNode){
- if(treeNode == nullptr){
- cout<<"invalid node pointer"<<endl;
- assert(false);
- }
- return treeNode->nodeValue;
- }
- TreeNode<T> *searchValueATree(TreeNode<T>* root, T value){
- if(!root)return nullptr;
- else if(root->nodeValue == value)return root;
- else {
- TreeNode<T>* temp1 = searchValueATree(root->leftChild, value);
- TreeNode<T>* temp2 = searchValueATree(root->rightSibling, value);
- if(temp1)return temp1;
- else return temp2;
- }
- }
- TreeNode<T> *getNodePtr(T value){
- LinkedList < TreeNode<T>* > _heap = innerList;
- ListNode< TreeNode<T>* > *iterator_1 = _heap.getHeadNode();
- while(iterator_1){
- TreeNode<T>* nodePointer = searchValueATree(iterator_1->getListData(), value);
- if(nodePointer)return nodePointer;
- iterator_1 = iterator_1->getRightNode();
- }
- return nullptr;
- }
- LinkedList < TreeNode<T>* > getHeapTreeExcludeMin(TreeNode<T>* treeNode){
- LinkedList< TreeNode<T>* > _heap;
- TreeNode<T> *lo, *temp = treeNode->leftChild;
- while(temp){
- lo = temp;
- temp = temp->rightSibling;
- lo->rightSibling = nullptr;
- _heap.pushFront(lo);
- }
- return _heap;
- }
- public:
- Binomial_Heap(){
- this->nodeCounter = this->treeCounter = 0;
- }
- // Binomial_Heap(Binomial_Heap heap1, Binomial_Heap heap2){
- // this->nodeCounter = heap1.nodeCounter + heap2.nodeCounter;
- // this->treeCounter = heap1.treeCounter + heap2.treeCounter;
- // this->innerList = unionLists(heap1.innerList, heap2.innerList);
- // heapify(this->innerList);
- // }
- void unionHeap(Binomial_Heap heap){
- this->nodeCounter = this->nodeCounter + heap.nodeCounter;
- this->treeCounter = this->treeCounter + heap.treeCounter;
- this->innerList = unionLists(this->innerList, heap.innerList);
- heapify(this->innerList);
- }
- unsigned int getNodeCounter() const {
- return nodeCounter;
- }
- unsigned int getTreeCounter() {
- treeCounter = countOnes(getNodeCounter());
- return treeCounter;
- }
- void insert(T newData){
- insertATreeInHeap(new TreeNode<T>(newData));
- nodeCounter++;
- }
- T extractMin(){
- LinkedList < TreeNode<T>* > _heap = innerList;
- LinkedList < TreeNode<T>* > newHeap, lo;
- TreeNode<T>* temp = getMinNodePtr();
- T mini = temp->nodeValue;
- ListNode< TreeNode<T>* > *iterator_1 = _heap.getHeadNode();
- while(iterator_1){
- if(iterator_1->getListData()->nodeValue != temp->nodeValue){
- newHeap.pushBack(iterator_1->getListData());
- }
- iterator_1 = iterator_1->getRightNode();
- }
- lo = getHeapTreeExcludeMin(temp);
- heapify(unionLists(newHeap, lo));
- nodeCounter--;
- return mini;
- }
- T findMin(){
- return getValueAt(getMinNodePtr());
- }
- void printTree(TreeNode<T>* temp){
- LinkedList< TreeNode<T>* > queueList;
- unsigned int levelNo = 0;
- temp->level = levelNo;
- queueList.pushBack(temp);
- while(!queueList.isEmpty()){
- if(queueList.frontVal()->leftChild){
- TreeNode<T> *curr = queueList.frontVal()->leftChild;
- curr->level = queueList.frontVal()->level + 1;
- while(curr){
- queueList.pushBack(curr);
- if(curr->rightSibling){
- curr->rightSibling->level = curr->level;
- }
- curr = curr->rightSibling;
- }
- }
- if(queueList.frontVal()->level > levelNo){
- cout<<endl;
- levelNo++;
- cout<<levelNo<<" -> ";
- }else if(levelNo==0){
- cout<<levelNo<<" -> ";
- }
- cout<<queueList.frontVal()->nodeValue<<" ";
- queueList.popFront();
- }
- cout<<endl;
- }
- void printHeap(){
- LinkedList < TreeNode<T>* > _heap = innerList;
- cout<<"//__________Heap___________"<<endl;
- ListNode< TreeNode<T>* > *iterator_1 = _heap.getHeadNode();
- unsigned int tree_cnt = 1;
- while(iterator_1){
- cout<<"Tree: "<<tree_cnt++<<endl;
- printTree(iterator_1->getListData());
- iterator_1 = iterator_1->getRightNode();
- }
- cout<<"___________________________//"<<endl;
- }
- bool existsValue(T val){
- return getNodePtr(val) != nullptr;
- }
- void decreaseKey(T oldVal, T newVal){
- LinkedList < TreeNode<T>* > _heap = innerList;
- if(newVal < oldVal && existsValue(_heap, oldVal)){
- TreeNode<T>* treeNode = getNodePtr(_heap, oldVal);
- TreeNode<T>* parent = treeNode->parent;
- treeNode->nodeValue = newVal;
- while(parent && treeNode->nodeValue < parent->nodeValue){
- swap(parent->nodeValue, treeNode->nodeValue);
- treeNode = parent;
- parent = treeNode->parent;
- }
- }
- else if(newVal > oldVal){
- cout<<"#decrease Key error"<<endl;
- }
- innerList = _heap;
- }
- void deleteFromBHeap(T val){
- LinkedList < TreeNode<T>* > _heap = innerList;
- if(_heap.getHeadNode() != nullptr && existsValue(_heap, val)){
- decreaseKey(_heap, val, INT_MIN);
- extractMin();
- //no need to decrease nodeCounter as done in extract min
- }
- }
- };
- //__________________________
- int main(){
- Binomial_Heap<int> heap1, heap2;
- heap1.insert(10);
- heap1.insert(20);
- heap1.insert(30);
- heap1.insert(40);
- heap1.insert(50);
- heap1.insert(60);
- heap1.printHeap();
- cout<<heap1.findMin()<<endl;
- cout<< heap1.extractMin() << endl;
- heap1.printHeap();
- heap2.insert(506);
- heap2.insert(404);
- heap2.printHeap();
- heap1.insert(10);
- heap1.printHeap();
- heap1.unionHeap(heap2);
- //Binomial_Heap<int> heap(heap1, heap2);
- heap1.printHeap();
- heap1.insert(333);
- cout<<heap1.findMin()<<endl;
- heap1.printHeap();
- cout<<heap1.findMin()<<endl;
- heap1.insert(4);
- heap1.insert(44);
- heap1.printHeap();
- cout<<heap1.extractMin()<<endl;
- heap1.printHeap();
- heap1.printHeap();
- heap2.insert(555);
- heap2.printHeap();
- cout<<heap2.findMin()<<endl;
- cout<<heap1.getNodeCounter()<<endl;
- cout<<heap1.getTreeCounter()<<endl;
- cout<<heap2.getNodeCounter()<<endl<<heap2.getTreeCounter()<<endl;
- // int n;
- // Binomial_Heap<string> hep;
- // cin>>n;
- // while(n--){
- // string a;
- // cin>>a;
- // hep.insert(a);
- // cout<<hep.findMin()<<endl;
- // hep.printHeap();
- // }
- // Binomial_Heap< Data<string, int> > heap;
- // heap.insert(Data<string, int>("sabit", 47));
- // heap.insert(Data<string, int>("Romiz", 48));
- // heap.insert(Data<string, int>("Rithm", 46));
- //
- // heap.printHeap();
- // cout<<heap.findMin()<<endl<<" "<<heap.getNodeCounter()<<endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement