Skip to content

Instantly share code, notes, and snippets.

@akshay-nm
Last active August 16, 2024 09:26
Show Gist options
  • Save akshay-nm/974407fecf97e7dfa09c7fb354deaeba to your computer and use it in GitHub Desktop.
Save akshay-nm/974407fecf97e7dfa09c7fb354deaeba to your computer and use it in GitHub Desktop.
Fibonacci heap

To implement the required operations (make_heap, insert, find_min, delete_min, and decrease_key) in a Fibonacci Heap in C++, I will guide you through each function step by step.

  1. Node Structure First, we need a Node structure to represent each element in the Fibonacci Heap:
struct Node {
    int key;
    int degree;
    bool marked;
    Node *parent;
    Node *child;
    Node *left;
    Node *right;

    Node(int k) : key(k), degree(0), marked(false), parent(nullptr), child(nullptr) {
        left = right = this;
    }
};
  1. FibonacciHeap Class Next, we'll define the FibonacciHeap class with the required operations:
class FibonacciHeap {
private:
    Node* min;
    int n;

    void link(Node* y, Node* x);
    void consolidate();
    void cut(Node* x, Node* y);
    void cascadingCut(Node* y);

public:
    FibonacciHeap() : min(nullptr), n(0) {}

    // Operations
    void makeHeap();
    void insert(int key);
    Node* findMin();
    int deleteMin();
    void decreaseKey(Node* x, int k);

    bool isEmpty() const {
        return min == nullptr;
    }
};
  1. Operation Implementations a. makeHeap Creates a new empty Fibonacci Heap.
void FibonacciHeap::makeHeap() {
    min = nullptr;
    n = 0;
}

b. insert Inserts a new key into the heap.

void FibonacciHeap::insert(int key) {
    Node* x = new Node(key);
    if (min == nullptr) {
        min = x;
    } else {
        x->left = min;
        x->right = min->right;
        min->right->left = x;
        min->right = x;
        if (key < min->key) {
            min = x;
        }
    }
    n++;
}

c. findMin Finds the minimum key in the heap.

Node* FibonacciHeap::findMin() {
    return min;
}

d. deleteMin Deletes the minimum key from the heap and returns its value.

int FibonacciHeap::deleteMin() {
    Node* z = min;
    if (z != nullptr) {
        if (z->child != nullptr) {
            Node* x = z->child;
            do {
                Node* next = x->right;
                x->left = min;
                x->right = min->right;
                min->right->left = x;
                min->right = x;
                x->parent = nullptr;
                x = next;
            } while (x != z->child);
        }

        z->left->right = z->right;
        z->right->left = z->left;

        if (z == z->right) {
            min = nullptr;
        } else {
            min = z->right;
            consolidate();
        }
        n--;
    }
    int minKey = z->key;
    delete z;
    return minKey;
}

e. decreaseKey Decreases the key of a node and restructures the heap if necessary.

void FibonacciHeap::decreaseKey(Node* x, int k) {
    if (k > x->key) {
        throw invalid_argument("New key is greater than current key.");
    }
    x->key = k;
    Node* y = x->parent;
    if (y != nullptr && x->key < y->key) {
        cut(x, y);
        cascadingCut(y);
    }
    if (x->key < min->key) {
        min = x;
    }
}
  1. Helper Functions These helper functions are used internally by the main operations:

a. link Links two trees of the same degree.

void FibonacciHeap::link(Node* y, Node* x) {
    y->left->right = y->right;
    y->right->left = y->left;

    y->parent = x;
    if (x->child == nullptr) {
        x->child = y;
        y->right = y;
        y->left = y;
    } else {
        y->left = x->child;
        y->right = x->child->right;
        x->child->right->left = y;
        x->child->right = y;
    }

    x->degree++;
    y->marked = false;
}

b. consolidate Consolidates the trees in the heap to maintain the Fibonacci Heap properties.

void FibonacciHeap::consolidate() {
    int D = floor(log2(n)) + 1;
    vector<Node*> A(D, nullptr);

    vector<Node*> rootList;
    Node* x = min;
    if (x != nullptr) {
        do {
            rootList.push_back(x);
            x = x->right;
        } while (x != min);
    }

    for (Node* w : rootList) {
        x = w;
        int d = x->degree;
        while (A[d] != nullptr) {
            Node* y = A[d];
            if (x->key > y->key) {
                swap(x, y);
            }
            link(y, x);
            A[d] = nullptr;
            d++;
        }
        A[d] = x;
    }

    min = nullptr;
    for (Node* y : A) {
        if (y != nullptr) {
            if (min == nullptr) {
                min = y;
                min->left = min;
                min->right = min;
            } else {
                y->left = min;
                y->right = min->right;
                min->right->left = y;
                min->right = y;
                if (y->key < min->key) {
                    min = y;
                }
            }
        }
    }
}

c. cut Cuts a node from its parent and adds it to the root list.

void FibonacciHeap::cut(Node* x, Node* y) {
    if (x->right == x) {
        y->child = nullptr;
    } else {
        x->right->left = x->left;
        x->left->right = x->right;
        if (y->child == x) {
            y->child = x->right;
        }
    }
    y->degree--;

    x->left = min;
    x->right = min->right;
    min->right->left = x;
    min->right = x;
    x->parent = nullptr;
    x->marked = false;
}

d. cascadingCut Performs a cascading cut to maintain the heap's structure.

void FibonacciHeap::cascadingCut(Node* y) {
    Node* z = y->parent;
    if (z != nullptr) {
        if (!y->marked) {
            y->marked = true;
        } else {
            cut(y, z);
            cascadingCut(z);
        }
    }
}
  1. Main Function Example Here's a simple main function to test the Fibonacci Heap:
int main() {
    FibonacciHeap heap;

    heap.makeHeap();
    heap.insert(10);
    heap.insert(3);
    heap.insert(15);
    heap.insert(6);

    cout << "Minimum: " << heap.findMin()->key << endl; // Should print 3

    cout << "Deleted Min: " << heap.deleteMin() << endl; // Should delete and print 3

    cout << "Minimum after deletion: " << heap.findMin()->key << endl; // Should print 6

    return 0;
}

This setup covers all operations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment