0% found this document useful (0 votes)
19 views93 pages

advanced data structures

The document is a practical record for the Advanced Data Structures course submitted by Joanisha Donna A at Madras Institute of Technology. It includes a bonafide certificate, course objectives, outcomes, a list of experiments, and detailed implementations of various data structures such as B-Trees and Red-Black Trees. Each experiment outlines the aim, algorithm, and source code for the implementation in C++.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views93 pages

advanced data structures

The document is a practical record for the Advanced Data Structures course submitted by Joanisha Donna A at Madras Institute of Technology. It includes a bonafide certificate, course objectives, outcomes, a list of experiments, and detailed implementations of various data structures such as B-Trees and Red-Black Trees. Each experiment outlines the aim, algorithm, and source code for the implementation in C++.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 93

IT23401

ADVANCED DATA STRUCTURES

A PRACTICAL RECORD

Submitted by

JOANISHA DONNA A
2023506004
B. Tech (4/8)

DEPARTMENT OF INFORMATION TECHNOLOGY

MADRAS INSTITUTE OF TECHNOLOGY


ANNA UNIVERSITY
CHENNAI – 600 044
April/May 2025
BONAFIDE CERTIFICATE

Name : Joanisha Donna A

Reg. No : 2023506004

Subject : IT23401 Advanced Data Structures

Department : Information Technology

Certified to the Bonafide record of practical work done by Miss.A.Joanisha

Donna in the IT23402 ADVANCED DATA STRUCURES during the

period January 2025 to April 2025.

Date:
Ms.R. Shanmugapriya
STAFF-IN-CHARGE

Submitted for the Practical Examination held on:

Internal Examiner External Examiner


IT23401 ADVANCED DATA STRUCTURES

COURSE OBJECTIVES

CO1 To learn about Amortized analysis

CO2 To learn about Balanced Trees and Heaps

CO3 To learn and implement different data structures using Object oriented concepts

CO4 To familiarize with Disjoint Sets and their implementation


CO5 To learn about the advanced graph algorithms for read world problem solving

COURSE OUTCOMES

CO1 Understand the usage of amortized analysis and Skip lists for real world
problem solving
CO2 Implement balanced trees through ADTs.

CO3 Understand and use Heap algorithms using amortized analysis.


CO4 Apply Disjoint sets for suitable applications

CO5 Analyze and apply the graph data structures for a given problem

CO-PO MATRIX
List of Experiments

S. Page
Date Name of the Experiment Signature
No. No
IMPLEMENTATION OF DYNAMIC
1. 09.01.25 TABLE USING AMORTIZED 1
OPERATIONS
IMPLEMENTATION OF BINARY COUNTER
2A. 23.01.25 USING AGGEGATE METHOD 7

IMPLEMENTATION OF BINARY COUNTER


2B. 23.01.25 USING POTENTIAL METHOD 13

IMPLEMENTATION OF DETERMINISTIC SKIP


3. 30.01.25 LIST USING TEMPLATES 19

IMPLEMENTATION OF AVL TREE WITH


4. 06.02.25 PROPER ROTATIONS 25

IMPLEMENTATION OF TOP DOWN SPLAY


5. 13.02.25 OPERATIONS USING AMORTIZED 41
ANALYSIS

IMPLEMENTATION OF B-TREE
6. 20.02.25 57

IMPLEMENTATION OF RED BLACK TREES


7. 20.02.25 67

IMPLEMENTATION OF TRIES TO SPELLCHECK


8A. 27.02.25 A TEXT 79

IMPLEMENTATION OF TRIES TO
8B. 27.02.25 AUTOCOMPLETE A TEXT 85

IMPLEMENTATION OF LEFTIST HEAPS USING


9. 06.03.25 TEMPLATES 91

IMPLEMENTATION OF FIBONACCI HEAP


10. 13.03.25 USING AMORTIZED ANALYSIS 99

IMPLEMENTATION OF TREAPS USING


11. 20.03.25 TEMPLATES 109
IMPLEMENTATION OF DISJOINT SET USING
12. 27.03.25 UNION/FIND ALGORTIHM 117

IMPLEMENTATION OF DFS APPLICATION


13. 03.04.25 -BICONNECTIVITY 121

IMPLEMENTATION OF BELLMAN FORD


14. 05.04.25 ALGORITHM 127

IMPLEMENTATION OF FLOYD WARSHALL


15. 24.04.25 ALGORTIHM 131

IMPLEMENTATION OF FORD FULKERSEN


16. 24.04.25 ALGORITHM 135
Ep No. 6
Date: 20/02/25

IMPLEMENTATION OF B TREE

AIM:
To implement the B Tree in C++.

ALGORITHM:

1. Input the minimum degree t of the B-Tree.

2. Initialize an empty B-Tree with degree t.

3. Repeat until the user exits:


 Display menu:
1. Insert
2. Search
3. Traverse
4. Exit

4. If choice = 1:
 Input key
 If root is null → create root and insert key
 Else if root is full → split and insert into proper child
 Else → insert into non-full node

5. If choice = 2:
 Input key
 Search from root using B-Tree search rules
 Output "Key found" or "Key not found"

6. If choice = 3:
 Recursively print all nodes level by level
 For each level, print the keys in that node

7. If choice = 4:
 End the program
SOURCE CODE:

#include <iostream>
using namespace std;

class BTreeNode {
public:
int *keys;
int t;
BTreeNode **C;
int n;
bool leaf;

BTreeNode(int _t, bool _leaf) {


t = _t;
leaf = _leaf;
keys = new int[2 * t - 1];
C = new BTreeNode *[2 * t];
n = 0;
}

void traverseWithLevels(int level = 0) {


cout << "Level " << level << ": ";
for (int i = 0; i < n; i++)
cout << keys[i] << " ";
cout << endl;
if (!leaf) {
for (int i = 0; i <= n; i++)
C[i]->traverseWithLevels(level + 1);
}
}

BTreeNode *search(int k) {
int i = 0;
while (i < n && k > keys[i])
i++;
if (i < n && keys[i] == k)
return this;
if (leaf)
return nullptr;
return C[i]->search(k);
}

void insertNonFull(int k) {
int i = n - 1;
if (leaf) {
while (i >= 0 && keys[i] > k) {
keys[i + 1] = keys[i];
i--;
}
keys[i + 1] = k;
n++;
} else {
while (i >= 0 && keys[i] > k)
i--;
if (C[i + 1]->n == 2 * t - 1) {
splitChild(i + 1, C[i + 1]);
if (keys[i + 1] < k)
i++;
}
C[i + 1]->insertNonFull(k);
}
}

void splitChild(int i, BTreeNode *y) {


BTreeNode *z = new BTreeNode(y->t, y->leaf);
z->n = t - 1;
for (int j = 0; j < t - 1; j++)
z->keys[j] = y->keys[j + t];
if (!y->leaf)
for (int j = 0; j < t; j++)
z->C[j] = y->C[j + t];
y->n = t - 1;
for (int j = n; j >= i + 1; j--)
C[j + 1] = C[j];
C[i + 1] = z;
for (int j = n - 1; j >= i; j--)
keys[j + 1] = keys[j];
keys[i] = y->keys[t - 1];
n++;
}
};

class BTree {
public:
BTreeNode *root;
int t;
BTree(int _t) {
root = nullptr;
t = _t;
}

void traverse() {
if (root)
root->traverseWithLevels();
else
cout << "Tree is empty\n";
}

BTreeNode *search(int k) {
return (root == nullptr) ? nullptr : root->search(k);
}

void insert(int k) {
if (root == nullptr) {
root = new BTreeNode(t, true);
root->keys[0] = k;
root->n = 1;
} else {
if (root->n == 2 * t - 1) {
BTreeNode *s = new BTreeNode(t, false);
s->C[0] = root;
s->splitChild(0, root);
int i = 0;
if (s->keys[0] < k)
i++;
s->C[i]->insertNonFull(k);
root = s;
} else
root->insertNonFull(k);
}
}
};

int main() {
int degree;
cout << "Enter the minimum degree of B-Tree: ";
cin >> degree;
BTree t(degree);
int choice, key;
while (true) {
OUTPUT:
cout << "\n1. Insert\n2. Search\n3. Traverse\n4. Exit\nEnter choice: ";
cin >> choice;
switch (choice) {
case 1:
cout << "Enter key to insert: ";
cin >> key;
t.insert(key);
break;
case 2:
cout << "Enter key to search: ";
cin >> key;
if (t.search(key))
cout << "Key found\n";
else
cout << "Key not found\n";
break;
case 3:
cout << "Tree structure:\n";
t.traverse();
break;
case 4:
return 0;
default:
cout << "Invalid choice\n";
}
}
}

RESULT:
Thus,B Tree has been successfully implemented with insert,search
and display functions in C++ and its output has been verified.
Exp No. 7
Date: 20/02/2025

IMPLEMENTATION OF RED -BLACK TREE

AIM:
To implement Red-Black trees and perform insertion,deletion and display
operations.

ALGORTIHM:
1. Insertion:
 Create a RED node for the key.
 Find its position in BST and attach it.
 Fix violations using fixInsert():
o If uncle is RED, recolor and move up.
o If uncle is BLACK, rotate and recolor.
 Ensure root is BLACK.
2. Fix Insertion:
 While parent is RED:
o If uncle is RED, recolor parent, uncle, and grandparent.
o If uncle is BLACK, rotate (left/right) and swap colors.
 Ensure root is BLACK.
3. Deletion:
 Find node (z) to delete.
 If z has one/no child, replace it with its child.
 If z has two children, replace with in-order successor.
 If deleted node was BLACK, fix balance.
SOURCE CODE:

#include <iostream>
using namespace std;

enum Color { RED, BLACK };

template <typename T>


class RedBlackTree {
private:
struct Node {
T data;
Color color;
Node* parent;
Node* left;
Node* right;
Node(T value) : data(value), color(RED), parent(nullptr), left(nullptr), right(nullptr)
{}
};

Node* root;

void rotateLeft(Node*& node) {


Node* child = node->right;
node->right = child->left;
if (node->right) node->right->parent = node;
child->parent = node->parent;
if (!node->parent) root = child;
else if (node == node->parent->left) node->parent->left = child;
else node->parent->right = child;
child->left = node;
node->parent = child;
}

void rotateRight(Node*& node) {


Node* child = node->left;
node->left = child->right;
if (node->left) node->left->parent = node;
child->parent = node->parent;
if (!node->parent) root = child;
else if (node == node->parent->left) node->parent->left = child;
else node->parent->right = child;
child->right = node;
node->parent = child;
}

void fixInsert(Node*& node) {


Node* parent = nullptr;
Node* grandparent = nullptr;
while (node != root && node->color == RED && node->parent->color == RED) {
parent = node->parent;
grandparent = parent->parent;
if (parent == grandparent->left) {
Node* uncle = grandparent->right;
if (uncle && uncle->color == RED) {
grandparent->color = RED;
parent->color = BLACK;
uncle->color = BLACK;
node = grandparent;
} else {
if (node == parent->right) {
rotateLeft(parent);
node = parent;
parent = node->parent;
}
rotateRight(grandparent);
swap(parent->color, grandparent->color);
node = parent;
}
} else {
Node* uncle = grandparent->left;
if (uncle && uncle->color == RED) {
grandparent->color = RED;
parent->color = BLACK;
uncle->color = BLACK;
node = grandparent;
} else {
if (node == parent->left) {
rotateRight(parent);
node = parent;
parent = node->parent;
}
rotateLeft(grandparent);
swap(parent->color, grandparent->color);
node = parent;
}
}
}
root->color = BLACK;
}

Node* minValueNode(Node* node) {


while (node->left) node = node->left;
return node;
}

void transplant(Node*& u, Node*& v) {


if (!u->parent) root = v;
else if (u == u->parent->left) u->parent->left = v;
else u->parent->right = v;
if (v) v->parent = u->parent;
}

void printHelper(Node* root, string indent, bool last) {


if (root) {
cout << indent;
if (root == this->root) {
cout << "Root --- ";
} else {
cout << (last ? "R----" : "L --- ");
}
indent += last ? " " : "| ";
cout << root->data << "(" << (root->color == RED ? "RED" : "BLACK") << ")\n";
printHelper(root->left, indent, false);
printHelper(root->right, indent, true);
}
}

public:
RedBlackTree() : root(nullptr) {}

void insert(T key) {


Node* node = new Node(key);
Node* parent = nullptr;
Node* current = root;
while (current) {
parent = current;
current = (node->data < current->data) ? current->left : current->right;
}
node->parent = parent;
if (!parent) root = node;
else if (node->data < parent->data) parent->left = node;
else parent->right = node;
fixInsert(node);
}

void remove(T key) {


Node* node = root, *z = nullptr, *x = nullptr, *y = nullptr;
while (node) {
if (node->data == key) z = node;
node = (node->data <= key) ? node->right : node->left;
}
if (!z) {
cout << "Key not found\n";
return;
}
y = z;
Color yOriginalColor = y->color;
if (!z->left) {
x = z->right;
transplant(z, z->right);
} else if (!z->right) {
x = z->left;
transplant(z, z->left);
} else {
y = minValueNode(z->right);
yOriginalColor = y->color;
x = y->right;
if (y->parent != z) {
transplant(y, y->right);
y->right = z->right;
y->right->parent = y;
}
transplant(z, y);
y->left = z->left;
y->left->parent = y;
y->color = z->color;
}
delete z;
if (yOriginalColor == BLACK) {
if (x) x->color = BLACK;
}
}

void printTree() {
OUTPUT:
if (!root) cout << "Tree is empty.\n";
else printHelper(root, "", true);
}
};

int main() {
RedBlackTree<int> rbtree;
int choice, value;
cout << "\n1. Insert\n2. Delete\n3. Print Tree\n4. Exit";
do {
cout << "Enter choice: ";
cin >> choice;
switch (choice) {
case 1: cout << "Enter value: "; cin >> value; rbtree.insert(value); break;
case 2: cout << "Enter value: "; cin >> value; rbtree.remove(value); break;
case 3: rbtree.printTree(); break;
case 4: break;
default: cout << "Invalid choice!\n";
}
} while (choice != 4);
return 0;
}

RESULT:
Thus a red black tree has been successfully implemented with insertion and
deletion operations.
Exp No. 8A
Date: 27/02/2025

IMPLEMENTATION OF TRIES TO
SPELLCHECK A TEXT

AIM:
To implement tries to perform spellcheck of a text in C++

ALGORITHM:

1. Initialize TrieNode:
 Create children[26] (for lowercase letters).
 Set isEndOfWord = false.

2. Insert Word:
 Traverse Trie, create nodes if missing.
 Mark last node as isEndOfWord = true.

3. Search Word:
 Traverse Trie; if any letter is missing, return false.
 If traversal completes, check isEndOfWord.

4. Main Execution:
 Insert n words.
 Search query word.
 Print "Correct spelling!" if found, else "Incorrect spelling!".
SOURCE CODE:

#include <iostream>
#include <vector>
using namespace std;

class TrieNode {
public:
TrieNode *children[26]; // For lowercase English letters
bool isEndOfWord;

TrieNode() {
isEndOfWord = false;
for (int i = 0; i < 26; i++)
children[i] = nullptr;
}
};

class Trie {
public:
TrieNode *root;

Trie() {
root = new TrieNode();
}

void insert(string word) {


TrieNode *node = root;
for (char c : word) {
int index = c - 'a';
if (!node->children[index])
node->children[index] = new TrieNode();
node = node->children[index];
}
node->isEndOfWord = true;
}

bool search(string word) {


TrieNode *node = root;
for (char c : word) {
int index = c - 'a';
if (!node->children[index])
return false;
OUTPUT:
node = node->children[index];
}
return node->isEndOfWord;
}
};

int main() {
Trie trie;
int n;
cout << "Enter the number of words to insert in dictionary: ";
cin >> n;

cout << "Enter words:\n";


for (int i = 0; i < n; i++) {
string word;
cin >> word;
trie.insert(word);
}

cout << "Enter a word to spellcheck: ";


string query;
cin >> query;

if (trie.search(query))
cout << "Correct spelling!\n";
else
cout << "Incorrect spelling!\n";

return 0;
}

RESULT:
Thus, Tries have been implemented to spellcheck the entered word and output has
been verified.
Exp No. 8B
Date: 27/02/2025

IMPLEMENTATION OF TRIES TO
AUTOCOMPLETE A TEXT

AIM:
To implement tries to perform autocomplete of a text in C++

ALGORTIHM:
1. Initialize TrieNode:
 Create children[26] (for lowercase letters).
 Set isEndOfWord = false.

2. Insert Word:
 Traverse Trie, create nodes if missing.
 Mark last node as isEndOfWord = true.

3. Autocomplete:
 Traverse Trie using the given prefix.
 If prefix exists, recursively print all possible completions.
 If missing, print "No suggestions found."

4. Main Execution:
 Insert n words.
 Input prefix and display autocomplete suggestions.
SOURCE CODE:
#include <iostream>
#include <vector>
using namespace std;

class TrieNode {
public:
TrieNode *children[26];
bool isEndOfWord;

TrieNode() {
isEndOfWord = false;
for (int i = 0; i < 26; i++)
children[i] = nullptr;
}
};

class Trie {
public:
TrieNode *root;

Trie() {
root = new TrieNode();
}

void insert(string word) {


TrieNode *node = root;
for (char c : word) {
int index = c - 'a';
if (!node->children[index])
node->children[index] = new TrieNode();
node = node->children[index];
}
node->isEndOfWord = true;
}

void autoCompleteHelper(TrieNode *node, string prefix) {


if (node->isEndOfWord)
cout << prefix << endl;
for (int i = 0; i < 26; i++) {
if (node->children[i])
autoCompleteHelper(node->children[i], prefix + char(i + 'a'));
OUTPUT:
}
}

void autoComplete(string prefix) {


TrieNode *node = root;
for (char c : prefix) {
int index = c - 'a';
if (!node->children[index]) {
cout << "No suggestions found.\n";
return;
}
node = node->children[index];
}
autoCompleteHelper(node, prefix);
}
};

int main() {
Trie trie;
int n;
cout << "Enter the number of words to insert in dictionary: ";
cin >> n;

cout << "Enter words:\n";


for (int i = 0; i < n; i++) {
string word;
cin >> word;
trie.insert(word);
}

cout << "Enter a prefix to get autocomplete suggestions: ";


string prefix;
cin >> prefix;

trie.autoComplete(prefix);

return 0;
}

RESULT:
Thus, Tries have been implemented to autocomplete a text and has been verified.
Exp No. 9
Date: 06/03/2025

IMPLEMENATATION OF LEFTIST HEAP


USING TEMPLATES

AIM:
To implement leftist heap using templates in C++.

ALGORTIHM:

1. Initialize Leftist Heap:


 Define Node with data, left, right, and rank.
 Set root = nullptr.

2. Merge Operation:
 Base cases: Return non-null node if the other is null.
 Ensure the smaller root remains.
 Recursively merge right subtree.
 Swap children if needed and update rank.

3. Insert Element:
 Merge root with a new node.

4. Delete Minimum Element:


 Replace root with the merge of left and right subtrees.

5. Heap Merge:
 Merge two heaps, setting the other’s root to nullptr.

6. Display Heap:
 Print heap structure recursively.

7. Main Execution
 Menu-driven insert, delete, display, and exit options.
SOURCE CODE:

#include <iostream>

using namespace std;

template <typename T>


class LeftistHeap {
private:
struct Node {
T data;
Node* left;
Node* right;
int rank;

Node(T val) : data(val), left(nullptr), right(nullptr), rank(1) {}


};

Node* root;

Node* merge(Node* h1, Node* h2) {


if (!h1) return h2;
if (!h2) return h1;
if (h1->data > h2->data) swap(h1, h2);

h1->right = merge(h1->right, h2);

if (!h1->left || (h1->left->rank < h1->right->rank)) {


swap(h1->left, h1->right);
}

h1->rank = (h1->right ? h1->right->rank : 0) + 1;


return h1;
}

public:
LeftistHeap() : root(nullptr) {}

void insert(T value) {


root = merge(root, new Node(value));
}

void deleteMin() {
if (!root) {
cout << "Heap is empty.\n";
return;
}
Node* oldRoot = root;
cout << "Deleted minimum element: " << root->data << endl;
root = merge(root->left, root->right);
delete oldRoot;
}

void merge(LeftistHeap<T>& other) {


root = merge(root, other.root);
other.root = nullptr;
}

bool isEmpty() {
return root == nullptr;
}

void display(Node* node, int depth = 0) {


if (node) {
display(node->right, depth + 1);
cout << string(depth * 4, ' ') << node->data << "\n";
display(node->left, depth + 1);
}
}

void display() {
if (!root) cout << "Heap is empty.\n";
else display(root);
}
};

int main() {
LeftistHeap<int> heap;
int choice, value;

while (true) {
cout << "\nLeftist Heap Menu:\n";
cout << "1. Insert\n2. Delete Min\n3. Display\n4. Exit\n";
cout << "Enter choice: ";
cin >> choice;

switch (choice) {
OUTPUT:
case 1:
cout << "Enter value: ";
cin >> value;
heap.insert(value);
break;
case 2:
heap.deleteMin();
break;
case 3:
heap.display();
break;
case 4:
return 0;
default:
cout << "Invalid choice!\n";
}
}
}

RESULT:
Thus, a leftist heap has been implemented with insertion,deleting min and display
operation using templates and has been executed successfully.
Exp No. 10
Date: 13/03/25

IMPLEMENTATION OF FIBONACCI HEAP


USING AMORTIZED ANALYSIS

AIM:
To implement Fibonacci heap using amortized analysis in C++.

ALGORITHM:

1. Insert:
 Create a new node.
 Insert it into the root list.
 Update the minimum node if necessary.
2. Get Minimum:
 Return the minimum node's key.
3. Extract Minimum:
 If the heap is not empty, remove the minimum node.
 Move children of the minimum node to the root list.
 Consolidate the heap by linking nodes of the same degree.
 Return the key of the extracted minimum node.
4. Consolidate:
 Traverse the root list and merge nodes of the same degree by linking
them.

SOURCE CODE:

#include <iostream>
#include <cmath>
using namespace std;

struct Node {
int key, degree;
Node *parent, *child, *left, *right;
bool mark;

Node(int val) {
key = val;
degree = 0;
parent = child = nullptr;
left = right = this;
mark = false;
}
[100]
};

class FibonacciHeap {
private:
Node* minNode;
int nodeCount;

void link(Node* y, Node* x) {


y->left->right = y->right;
y->right->left = y->left;
y->parent = x;
if (!x->child) {
x->child = y;
y->left = y->right = y;
} else {
y->right = x->child;
y->left = x->child->left;
x->child->left->right = y;
x->child->left = y;
}
x->degree++;
y->mark = false;
}

void consolidate() {
int maxDegree = log2(nodeCount) + 1;
Node* A[maxDegree] = {nullptr};
Node* start = minNode;
Node* current = minNode;
do {
Node* x = current;
int d = x->degree;
while (A[d]) {
Node* y = A[d];
if (x->key > y->key) swap(x, y);
link(y, x);
A[d] = nullptr;
d++;
}
A[d] = x;
current = current->right;
} while (current != start);
minNode = nullptr;
for (int i = 0; i < maxDegree; i++) {
if (A[i]) {
if (!minNode) {
minNode = A[i];
minNode->left = minNode->right = minNode;
} else {
A[i]->left = minNode;
A[i]->right = minNode->right;
minNode->right->left = A[i];
minNode->right = A[i];
if (A[i]->key < minNode->key)
minNode = A[i];
}
}
}
}

public:
FibonacciHeap() : minNode(nullptr), nodeCount(0) {}

void insert(int key) {


Node* newNode = new Node(key);
if (!minNode) {
minNode = newNode;
} else {
newNode->right = minNode->right;
newNode->left = minNode;
minNode->right->left = newNode;
minNode->right = newNode;
if (key < minNode->key) minNode = newNode;
}
nodeCount++;
}

int getMin() {
return minNode ? minNode->key : -1;
}

int extractMin() {
if (!minNode) return -1;
Node* min = minNode;
if (min->child) {
Node* child = min->child;
do {
Node* nextChild = child->right;
child->left = minNode;
child->right = minNode->right;
minNode->right->left = child;
minNode->right = child;
child->parent = nullptr;
child = nextChild;
} while (child != min->child);
}
min->left->right = min->right;
min->right->left = min->left;
int minValue = min->key;
if (min == min->right) {
minNode = nullptr;
} else {
minNode = min->right;
consolidate();
}
delete min;
nodeCount--;
return minValue;
}
};

int main() {
FibonacciHeap heap;
int choice, value;
while (true) {
cout << "\nFibonacci Heap Menu:\n";
cout << "1. Insert\n2. Get Min\n3. Extract Min\n4. Exit\nEnter choice:
";
cin >> choice;
switch (choice) {
case 1:
cout << "Enter value to insert: ";
cin >> value;
heap.insert(value);
cout << "Inserted " << value << "\n";
break;
case 2:
cout << "Minimum value: " << heap.getMin() << "\n";
break;
case 3:
cout << "Extracted Min: " << heap.extractMin() << "\n";
break;
OUTPUT:
case 4:
cout << "Exiting...\n";
return 0;
default:
cout << "Invalid choice! Try again.\n";
}
}
return 0;
}

RESULT:
Thus Fibonacci Heap has been implemented successfully using
amortized analysis and its output has been verified.
Exp No. 11
Date: 20/03/25

IMPLEMENTATION OF TREAPS

AIM:
To implement Treaps in c++.

ALGORITHM:

1. Start
2. Initialize root as nullptr.
3. Repeat until the user chooses to exit:
 Display the menu:
4. Read user choice.
 Switch based on choice:
o Case 1: Insert
 Prompt user to enter a key.
 Call insert(root, key) and update root.
o Case 2: Delete
 Prompt user to enter a key.
 Call deleteNode(root, key) and update root.
o Case 3: Display
 Call inorder(root) to print the Treap in inorder format.
o Case 4: Exit
 Print exit message and break the loop.
o Default:
 Print invalid choice message.
5. End

SOURCE CODE:

#include <iostream>
#include <cstdlib>
using namespace std;

struct Node {
int key, priority;
Node *left, *right;

Node(int k) {
key = k;
priority = rand();
left = right = nullptr;
}
};

// Function to rotate right


Node* rotateRight(Node* y) {
Node* x = y->left;
y->left = x->right;
x->right = y;
return x;
}

// Function to rotate left


Node* rotateLeft(Node* x) {
Node* y = x->right;
x->right = y->left;
y->left = x;
return y;
}

// Function to insert a key


Node* insert(Node* root, int key) {
if (!root) return new Node(key);

if (key < root->key) {


root->left = insert(root->left, key);
if (root->left->priority > root->priority)
root = rotateRight(root);
} else {
root->right = insert(root->right, key);
if (root->right->priority > root->priority)
root = rotateLeft(root);
}
return root;
}

// Function to delete a key


Node* deleteNode(Node* root, int key) {
if (!root) return root;

if (key < root->key)


root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
else {
if (!root->left)
return root->right;
else if (!root->right)
return root->left;

if (root->left->priority > root->right->priority)


root = rotateRight(root), root->right = deleteNode(root->right, key);
else
root = rotateLeft(root), root->left = deleteNode(root->left, key);
}
return root;
}

// Inorder traversal
void inorder(Node* root) {
if (root) {
inorder(root->left);
cout << "(" << root->key << ", " << root->priority << ") ";
inorder(root->right);
}
}

int main() {
Node* root = nullptr;
int choice, key;

do {
cout << "\nTreap Menu:\n";
cout << "1. Insert\n";
cout << "2. Delete\n";
cout << "3. Display (Inorder)\n";
cout << "4. Exit\n";
cout << "Enter your choice: ";
cin >> choice;

switch (choice) {
case 1:
cout << "Enter key to insert: ";
cin >> key;
root = insert(root, key);
break;
case 2:
cout << "Enter key to delete: ";
cin >> key;
OUTPUT:
root = deleteNode(root, key);
break;
case 3:
cout << "Inorder traversal of the Treap:\n";
inorder(root);
cout << endl;
break;
case 4:
cout << "Exiting...\n";
break;
default:
cout << "Invalid choice, try again.\n";
}
} while (choice != 4);

return 0;
}

RESULT:
Thus ,Treaps with insert,delete and display functions has been
implemented and its output has been verified successfully.
Exp No. 12
Date: 27/03/25

IMPLEMENTATION OF DISJOINT SETS


USING UNION/FIND ALGORITHM

AIM:
To implement disjoint sets using union/find algorithm in C++.

ALGORITHM:

1. Initialize parent[i] = i and rank[i] = 0 for all elements.


2. Find(x): Recursively return the root of x, apply path compression
(parent[x] = find(parent[x])).
3. Union(x, y): Find roots of both, attach lower-rank tree under higher one,
or increase rank if equal.
4. makeSet(): Initialize the disjoint set for n elements.
5. isSameSet(x, y): Return true if find(x) == find(y).
6. Main():
 Call makeSet()
 Perform union on fixed pairs
 Print parent array
 Check and print if pairs are in the same set

SOURCE CODE:

#include <iostream>
using namespace std;

const int SIZE = 7;


int parent[SIZE], rankArr[SIZE];

void makeSet() {
for (int i = 0; i < SIZE; i++) {
parent[i] = i;
rankArr[i] = 0;
}
}

int find(int x) {
if (parent[x] != x)
parent[x] = find(parent[x]);
return parent[x];
}
OUTPUT:
void unionSets(int x, int y) {
int xroot = find(x);
int yroot = find(y);
if (xroot == yroot) return;
if (rankArr[xroot] < rankArr[yroot])
parent[xroot] = yroot;
else if (rankArr[xroot] > rankArr[yroot])
parent[yroot] = xroot;
else {
parent[yroot] = xroot;
rankArr[xroot]++;
}
}

bool isSameSet(int x, int y) {


return find(x) == find(y);
}

int main() {
makeSet();
unionSets(0, 1);
unionSets(1, 2);
unionSets(2, 3);
unionSets(3, 4);
unionSets(5, 6);

cout << "Disjoint Set after Union operations:\n";


cout << "Element: ";
for (int i = 0; i < SIZE; i++) cout << i << " ";
cout << "\nParent: ";
for (int i = 0; i < SIZE; i++) cout << find(i) << " ";
cout << "\n\n";

cout << "Are 0 and 4 in the same set? " << (isSameSet(0, 4) ? "Yes" :
"No") << endl;
cout << "Are 5 and 6 in the same set? " << (isSameSet(5, 6) ? "Yes" :
"No") << endl;

return 0;
}

RESULT:
Thus Disjoint set has been implemented using Union Algorithm.
Exp No. 13
Date: 03/04/25

IMPLEMENTATION OF DFS APPLICATION-


BICONNECTIVITY

AIM:
To implement a program to check whether an Undirected graph is
Biconnected in C++.

ALGORITHM:
1. Initialize
 Create arrays:
o visited[]: Track visited nodes
o disc[]: Discovery time of each node during DFS
o low[]: Lowest discovery time reachable from the node
o parent[]: Parent of each node in DFS tree
 Use a set to store articulation points.

2. DFS Traversal
For each unvisited node u:
1. Mark u as visited.
2. Set its discovery time and low value.
3. For each adjacent node v:
o If v is not visited:
 Set u as parent of v.
 Recursively call DFS for v.
 After DFS:
 Update low[u] = min(low[u], low[v])
 If:
 u is root and has more than one child → u
is an articulation point
 low[v] >= disc[u] → u is an articulation
point
o If v is visited and not parent of u, update low[u] = min(low[u],
disc[v])

3. Result
 If no articulation points were found → graph is biconnected.
 Else → print the articulation points.
SOURCE CODE:

#include <iostream>
#include <vector>
#include <set>
using namespace std;

class Graph {
int V;
vector<vector<int>> adj;
void DFS(int u, vector<bool>& visited, vector<int>& disc, vector<int>&
low, vector<int>& parent, set<int>& articulationPoints, int& time) {
visited[u] = true;
disc[u] = low[u] = ++time;
int children = 0;
for (int v : adj[u]) {
if (!visited[v]) {
children++;
parent[v] = u;
DFS(v, visited, disc, low, parent, articulationPoints, time);
low[u] = min(low[u], low[v]);
if (parent[u] == -1 && children > 1)
articulationPoints.insert(u);
if (parent[u] != -1 && low[v] >= disc[u])
articulationPoints.insert(u);
}
else if (v != parent[u]) {
low[u] = min(low[u], disc[v]);
}
}
}
public:
Graph(int V) {
this->V = V;
adj.resize(V);
}
void addEdge(int u, int v) {
adj[u].push_back(v);
adj[v].push_back(u);
}
void findArticulationPoints() {
vector<bool> visited(V, false);
vector<int> disc(V), low(V), parent(V, -1);
set<int> articulationPoints;
OUTPUT:
int time = 0;
for (int i = 0; i < V; i++) {
if (!visited[i])
DFS(i, visited, disc, low, parent, articulationPoints, time);
}
if (articulationPoints.empty())
cout << "Graph is Biconnected\n";
else {
cout << "Articulation Points: ";
for (int ap : articulationPoints)
cout << ap << " ";
cout << endl;
}
}
};

int main() {
Graph g(5);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(2, 1);
g.addEdge(0, 3);
g.addEdge(3, 4);
g.findArticulationPoints();
return 0;
}

RESULT:
Thus an program to find whether an undirected graph is biconnected
or not has been executed and its output has been verified.
Exp No. 14
Date: 05/04/25

IMPLEMENTATION OF BELLMAN FORD


ALGORITHM

AIM:
To implement Bellman ford algorithm in C++.

ALGORITHM:
1. Input:
 Number of vertices V, number of edges E
 List of edges with u, v, and weight
 Source vertex src
2. Initialization:
 Set distance to all vertices as ∞ (or a large value like 1e9)
 Set distance to source vertex as 0
3. Relaxation Step (Repeat V - 1 times):
 For each edge (u, v, weight):
o If distance[u] + weight < distance[v], update distance[v] =
distance[u] + weight
4. Negative Cycle Check:
 For each edge (u, v, weight):
o If distance[u] + weight < distance[v], report negative weight
cycle
5. Output:
 Print shortest distances from source to all vertices

SOURCE CODE:

#include <iostream>
#include <vector>
using namespace std;
struct Edge {
int u, v, w;
};
int main() {
int V, E, src;
cout << "Enter number of vertices: ";
cin >> V;
cout << "Enter number of edges: ";
cin >> E;
cout << "Enter source vertex (0 to " << V-1 << "): ";
OUTPUT:
cin >> src;
vector<Edge> edges(E);
cout << "Enter each edge in format: u v weight\n";
for (int i = 0; i < E; i++) {
cout << "Edge " << i + 1 << ": ";
cin >> edges[i].u >> edges[i].v >> edges[i].w;
}
vector<int> dist(V, 1e9);
dist[src] = 0;

for (int i = 0; i < V - 1; i++) {


for (int j = 0; j < E; j++) {
int u = edges[j].u;
int v = edges[j].v;
int w = edges[j].w;
if (dist[u] != 1e9 && dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
}
}
}
for (int j = 0; j < E; j++) {
int u = edges[j].u;
int v = edges[j].v;
int w = edges[j].w;
if (dist[u] != 1e9 && dist[u] + w < dist[v]) {
cout << "Negative weight cycle detected\n";
return 0;
}
}
cout << "\nShortest distances from source vertex " << src << ":\n";
for (int i = 0; i < V; i++) {
cout << "To vertex " << i << ": ";
if (dist[i] == 1e9) cout << "INF\n";
else cout << dist[i] << "\n";
}

return 0;
}

RESULT:
Thus a program to find the shortest path from a source vertex using
Bellman Ford algorithm has been executed and its output has been verified.
Exp No. 15
Date: 24/04/25

IMPLEMENTATION OF FLOYD-WARSHALL
ALGORTIHM

AIM:
To implement Floyd Warshall algorithm in c++.

ALGORITHM:
1. Input number of vertices V and adjacency matrix graph[V][V], using a large number for
no edge
2. Replace large numbers (>=999999) with infinity (INT_MAX).
3. Set dist = graph.
4. For each vertex k:
 For each pair (i, j):
o If dist[i][k] and dist[k][j] are not infinity:
 Update dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]).
5. Output the distance matrix:
 Print "INF" for infinity, else print distance value.
6. End.

SOURCE CODE:
#include <iostream>
#include <vector>
#include <limits>

using namespace std;

void floydWarshall(vector<vector<int>>& graph, int V) {


vector<vector<int>> dist = graph;

for (int k = 0; k < V; k++) {


for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][k] != numeric_limits<int>::max() && dist[k][j] !=
numeric_limits<int>::max()) {
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
}
}
}
}
OUTPUT:
cout << "The shortest distances between every pair of vertices:" << endl;
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][j] == numeric_limits<int>::max())
cout << "INF" << " ";
else
cout << dist[i][j] << " ";
}
cout << endl;
}
}

int main() {
int V;
cout << "Enter the number of vertices: ";
cin >> V;

vector<vector<int>> graph(V, vector<int>(V));


cout << "Enter the adjacency matrix (use a very large value for no direct edge, e.g.,
999999):" << endl;

for (int i = 0; i < V; i++) {


for (int j = 0; j < V; j++) {
cin >> graph[i][j];
}
}
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (graph[i][j] >= 999999)
graph[i][j] = numeric_limits<int>::max();
}
}

floydWarshall(graph, V);

return 0;
}

RESULT:
Thus Floyd-Warshall algorithm has been executed in C++ successfully.
Exp No. 16
Date: 24/04/25

IMPLEMENTATION OF FORD FULKERSON


ALGORITHM
AIM:
To implement Ford Fulkerson algorithm in C++.

ALGORITHM:
1. Start.
2. Input the number of vertices V and edges E.
3. Input each edge (from, to, capacity) and build the graph.
4. Input the source and sink vertices.
5. Initialize:
 residualGraph = graph
 maxFlow = 0
6. While there is a path from source to sink in residualGraph (found using BFS):
 Find the minimum capacity pathFlow along the found path.
 Update the residual capacities:
o Subtract pathFlow along the forward edges.
o Add pathFlow along the reverse edges.
 Add pathFlow to maxFlow.
7. Output the maxFlow.
8. End.

SOURCE CODE:
#include <iostream>
#include <vector>
#include <queue>
#include <climits>

using namespace std;


bool bfs(vector<vector<int>>& residualGraph, int source, int sink, vector<int>& parent) {
int V = residualGraph.size();
vector<bool> visited(V, false);
queue<int> q;
q.push(source);
visited[source] = true;

while (!q.empty()) {
int u = q.front();
q.pop();

for (int v = 0; v < V; v++) {


if (!visited[v] && residualGraph[u][v] > 0) {
parent[v] = u;
visited[v] = true;
q.push(v);
if (v == sink) return true; // Path found
}
}
}
return false; // No path
}

int fordFulkerson(vector<vector<int>>& graph, int source, int sink) {


int V = graph.size();
vector<vector<int>> residualGraph = graph;
vector<int> parent(V);
int maxFlow = 0;

while (bfs(residualGraph, source, sink, parent)) {


int pathFlow = INT_MAX;

for (int v = sink; v != source; v = parent[v]) {


int u = parent[v];
pathFlow = min(pathFlow, residualGraph[u][v]); // Find minimum capacity
}

for (int v = sink; v != source; v = parent[v]) {


int u = parent[v];
residualGraph[u][v] -= pathFlow;
residualGraph[v][u] += pathFlow; // Adjust reverse path
}

maxFlow += pathFlow; // Add path flow to total flow


}
return maxFlow;
}

int main() {
int V, E;
cout << "Enter number of vertices and edges: ";
cin >> V >> E;

vector<vector<int>> graph(V, vector<int>(V, 0));


cout << "Enter edges (from, to, capacity):" << endl;
for (int i = 0; i < E; i++) {
OUTPUT:

\
int u, v, capacity;
cin >> u >> v >> capacity;
graph[u][v] = capacity;
}

int source, sink;


cout << "Enter source and sink: ";
cin >> source >> sink;

cout << "Maximum Flow: " << fordFulkerson(graph, source, sink) << endl;

return 0;
}

RESULT:
Thus Ford Fulkerson’s algorithm has been implemented in C++.

You might also like