Ada
Ada
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
int comparison_count = 0;
int main(){
    srand(time(NULL));      // This will call srand only once in the beginning
    int size;
    cout<<"Enter the size of array"<<endl;
    cin>>size;
    int *a= new int[size];
    cout<<"Enter the array "<<endl;
    for(int i = 0; i < size; i++){
        cin >> a[i];
    }
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
int comparison_count = 0;
int main() {
    srand(time(NULL));    // Seed the random number generator
    int size;
    cout << "Enter the size of array: ";
    cin >> size;
    int *a = new int[size];
randomised_quicksort(a, 0, size-1);
// Question 2. Write a program to find the ith smallest element of an array using
Randomized Select.
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int m = partition(a, p, q); // Partition the array and get pivot index
    if (i == k) {
         return a[m];                   // Found the ith smallest element
    }
    else if (i < k) {
         return randomised_select(a, p, m - 1, i); // Search in the left subarray
    }
    else {
         return randomised_select(a, m + 1, q, i - k); // Search in the right
subarray
    }
}
int main() {
    srand(time(NULL));
    int size, i;
    cout << "Enter the size of the array: ";
    cin >> size;
    cout << "Enter the value of i (for the ith smallest element): ";
    cin >> i;
    delete[] a;
    return 0;
}
#include <iostream>
#include <vector>
using namespace std;
struct UnionNode {
    int data;
    UnionNode* parent;
    int size;
     UnionNode(int ele){
         data = ele;
         parent = this;
         size = 1;
     }
};
class UnionFind {
    std::vector<UnionNode*> pointersVector;
public:
    void makeUnionFind(int vertices) {
        for (int i = 0; i < vertices; i++) {
            pointersVector.push_back(new UnionNode(i));
        }
    }
         if (root1 != root2) {
             if (root1->size < root2->size) {
                 root1->parent = root2;
                 root2->size += root1->size;
             } else {
                 root2->parent = root1;
                 root1->size += root2->size;
             }
         }
     }
     void display() {
         for (int i = 0; i < pointersVector.size(); i++) {
             cout << i << " : " << find(i) << endl;
         }
     }
     ~UnionFind() {
         for (auto node : pointersVector) {
             delete node;
         }
     }
};
struct Node{
    int source;
    int destination;
    int weight;
    Node * next;
    Node(int Source,int Destination,int Weight){
        destination= Destination;
        weight = Weight;
        source = Source;
        next=NULL;
    }
};
class LinkedList{
    Node * head;
    public:
    LinkedList(){
        head=NULL;
    }
    Node * getHeadNode(){return head;}
    bool isEmpty(){return head==NULL;}
    void addToHead(int source,int destination,int weight);
    Node * search(int ele);
    void display();
};
void LinkedList::display(){
    cout<<"[";
    Node * temp = head;
    while(temp!=NULL){
        cout<<"{"<<temp->source<<" ,"<<temp->destination<<","<<temp->weight<<"},";
        temp=temp->next;
    }
    cout<<"\b]\n";
}
class Graph{
    int vertex;
    LinkedList * adjList;
    public:
    Graph(int n){
        vertex = n;
        adjList = new LinkedList[vertex];
    }
    void addEdge(int u,int v,int weight);
    void display();
    void kruskal();
};
    if(adjList[v].search(u)==NULL)
        adjList[v].addToHead(v,u,weight);
}
void Graph::display(){
    for (int i = 0; i < vertex; i++)
    {
        cout<<"List of vertex "<<i<<": ";
        adjList[i].display();
    }
}
void Graph::kruskal() {
    std::vector<Node*> edges;
    UnionFind uf;
    uf.makeUnionFind(vertex);
    int mstWeight = 0;
    cout << "MST: [";
    for (auto edge : edges) {
        if (uf.find(edge->source) != uf.find(edge->destination)) {
            mstWeight += edge->weight;
            cout << "\n\t{" << edge->source << "," << edge->destination << "," <<
edge->weight << "}";
            uf.Union(edge->source, edge->destination);
        }
    }
    cout << "\n]";
    cout << "\nMinimum Cost: " << mstWeight;
}
int main(){
    cout<<"Enter Number of vertex in the Graph:\n";
    int n;
    cin>>n;
Graph A(n);
    while(true){
        int u,v,weight;
        cout<<"\nEnter 1 to addEdge\n"
        <<"Enter 2 to display graph\n"
        <<"Enter 3 to find mst using Kruskal\n"
        <<"Enter 4 to exit\n"
        <<"enter choice:";
        int ch;
        cin>>ch;
        switch (ch)
        {
        case 1:
            cout<<"\nEnter edge u and v and weight : ";
            cin>>u>>v>>weight;
            if((u<n && u>=0) && (v<n && v>=0)){
                 A.addEdge(u,v,weight);}
            break;
        case 2:
            A.display();
            break;
        case 3:
            A.kruskal();
            break;
        case 4:
            exit(0);
        default:
            break;
        }
    }
}
#include <iostream>
#include <climits>
using namespace std;
struct Node {
    int data;
    int weight;
    Node* next;
    Node(int ele, int Weight) {
        data = ele;
        weight = Weight;
        next = NULL;
    }
};
class LinkedList {
    Node* head;
public:
    LinkedList() { head = NULL; }
    void addToHead(int ele, int weight);
    Node* search(int ele);
    void display();
    bool isEmpty() { return head == NULL; }
    Node* getHeadNode() { return head; }
};
void LinkedList::display() {
    cout << "[ ";
    Node* temp = head;
    while (temp != NULL) {
        cout << "{v:" << temp->data << ",w:" << temp->weight << "} ,";
        temp = temp->next;
    }
    cout << "\b ]\n";
}
class DirectedGraph {
    int vertex;
    LinkedList* adjList;
public:
     DirectedGraph(int n) {
         vertex = n;
         adjList = new LinkedList[vertex];
     }
     ~DirectedGraph() { delete[] adjList; }
     void addEdge(int u, int v, int weight);
     int bellmanFord(int source, int destination);
     void display();
};
     // Initialize distances
     for (int i = 0; i < vertex; i++) {
         dist[i] = INT_MAX;
     }
     dist[source] = 0;
                 // Relaxation condition
                 if (dist[u] != INT_MAX &&
                     dist[u] + weight < dist[v]) {
                     dist[v] = dist[u] + weight;
                     updated = true;
                 }
                 current = current->next;
             }
         }
            current = current->next;
        }
    }
    // Clean up
    delete[] dist;
void DirectedGraph::display() {
    for (int i = 0; i < vertex; i++) {
        cout << "Adjacency List of vertex " << i << ": ";
        adjList[i].display();
    }
}
int main() {
    int n;
    cout << "Enter Number of vertices in the Graph: ";
    cin >> n;
    if (n <= 0) {
        cout << "Invalid number of vertices!" << endl;
        return 0;
    }
    DirectedGraph A(n);
    int ch = 0;
    while (ch != 4) {
        int u, v, weight;
        cout << "\nMenu:\n"
             << "1. Add Edge\n"
             << "2. Display Graph\n"
             << "3. Run Bellman-Ford\n"
             << "4. Exit\n"
             << "Enter your choice: ";
        cin >> ch;
        switch (ch) {
            case 1:
                cout << "Enter edge (u, v) and its weight: ";
                cin >> u >> v >> weight;
                if ((u < n && u >= 0) && (v < n && v >= 0)) {
                    A.addEdge(u, v, weight);
                } else {
                    cout << "Invalid vertices!" << endl;
                }
                break;
            case 2:
                A.display();
                break;
            case 3:
                cout << "Enter source and destination vertices: ";
                cin >> u >> v;
                if ((u < n && u >= 0) && (v < n && v >= 0)) {
                     int result = A.bellmanFord(u, v);
                     if (result == -1) {
                         cout << "No path exists or negative weight cycle detected
from vertex " << u << " to vertex " << v << endl;
                     } else {
                         cout << "Shortest Path from vertex " << u << " to vertex "
<< v << " : " << result << endl;
                     }
                } else {
                     cout << "Invalid vertices!" << endl;
                }
                break;
            case 4:
                cout << "Exiting program." << endl;
                break;
            default:
                cout << "Invalid choice!" << endl;
        }
    }
     return 0;
}
#include <iostream>
#include <vector>
using namespace std;
// A B-Tree node
class BTreeNode {
public:
    vector<int> keys; // A vector to store keys
    vector<BTreeNode*> children; // A vector to store child pointers
    bool isLeaf; // True if the node is a leaf
    int t; // Minimum degree (defines the range for the number of keys)
    if (isLeaf) {
        return nullptr;
    }
    return children[i]->search(key);
}
    if (isLeaf) {
        while (i >= 0 && keys[i] > key) {
             i--;
        }
        keys.insert(keys.begin() + i + 1, key);
    } else {
        while (i >= 0 && keys[i] > key) {
             i--;
        }
        if (children[i + 1]->keys.size() == 2 * t - 1) {
             splitChild(i + 1, children[i + 1]);
             if (keys[i + 1] < key) {
                  i++;
             }
        }
        children[i + 1]->insertNonFull(key);
    }
}
// Split the child of this node
void BTreeNode::splitChild(int i, BTreeNode* y) {
    BTreeNode* z = new BTreeNode(y->t, y->isLeaf);
    z->keys.assign(y->keys.begin() + t, y->keys.end());
    y->keys.resize(t - 1);
     if (!y->isLeaf) {
         z->children.assign(y->children.begin() + t, y->children.end());
         y->children.resize(t);
     }
     children.insert(children.begin() + i + 1, z);
     keys.insert(keys.begin() + i, y->keys[t - 1]);
}
// A B-Tree
class BTree {
private:
    BTreeNode* root;
    int t;
public:
    BTree(int degree) : root(nullptr), t(degree) {}
     void traverse() {
         if (root) {
             root->traverse();
         }
     }
// Main function
int main() {
    int degree, choice, value;
    cout << "Enter the degree of the B-Tree: ";
    cin >> degree;
    BTree tree(degree);
    do {
        cout << "\nB-Tree Operations:" << endl;
        cout << "1. Insert" << endl;
        cout << "2. Search" << endl;
        cout << "3. Traverse" << endl;
        cout << "4. Exit" << endl;
        cout << "Enter your choice: ";
        cin >> choice;
        switch (choice) {
        case 1:
            cout << "Enter value to insert: ";
            cin >> value;
            tree.insert(value);
            break;
        case 2:
            cout << "Enter value to search: ";
            cin >> value;
            if (tree.search(value)) {
                 cout << value << " is found in the B-Tree." << endl;
            } else {
                 cout << value << " is not found in the B-Tree." << endl;
            }
            break;
        case 3:
            cout << "B-Tree in sorted order: ";
            tree.traverse();
            cout << endl;
            break;
        case 4:
            cout << "Exiting program. Thank you!" << endl;
            break;
        default:
            cout << "Invalid choice. Please try again." << endl;
        }
    } while (choice != 4);
    return 0;
}
//Question 6. Write a program to implement the Tree Data structure, which supports
the following operations:
//          a. Insert
//          b. Search
#include <iostream>
using namespace std;
     // Constructor
     TreeNode(int value) : data(value), left(nullptr), right(nullptr) {}
};
public:
    // Constructor
    BinaryTree() : root(nullptr) {}
     // Insert a value into the tree
     void insert(int value) {
         root = insertNode(root, value);
         cout << "Inserted " << value << " into the tree." << endl;
     }
// Main function
int main() {
    BinaryTree tree;
    int choice, value;
     do {
         cout << "\nBinary Tree Operations:" << endl;
         cout << "1. Insert" << endl;
         cout << "2. Search" << endl;
         cout << "3. Display" << endl;
         cout << "4. Exit" << endl;
         cout << "Enter your choice: ";
         cin >> choice;
         switch (choice) {
         case 1:
             cout << "Enter value to insert:   ";
             cin >> value;
             tree.insert(value);
             break;
         case 2:
             cout << "Enter value to search:   ";
             cin >> value;
             tree.search(value);
             break;
         case 3:
             tree.display();
             break;
         case 4:
             cout << "Exiting program. Thank   you!" << endl;
             break;
         default:
             cout << "Invalid choice. Please   try again." << endl;
         }
     } while (choice != 4);
    return 0;
}
Question 7. Write a program to search a pattern in a given text using the KMP
algorithm.
#include   <iostream>
#include   <vector>
#include   <string>
#include   <limits>
class KMPSearch {
public:
    // Compute the longest proper prefix which is also a suffix array
    static vector<int> computeLPSArray(const string& pattern) {
        int m = pattern.length();
        vector<int> lps(m, 0);
        while (i < m) {
            if (pattern[i] == pattern[len]) {
                len++;
                lps[i] = len;
                i++;
            }
            else {
                // If characters don't match
                if (len != 0) {
                     len = lps[len - 1];
                }
                else {
                     lps[i] = 0;
                     i++;
                }
            }
        }
        return lps;
    }
        int n = text.length();
        int m = pattern.length();
         while (i < n) {
             // If characters match, increment both indices
             if (pattern[j] == text[i]) {
                 j++;
                 i++;
             }
         return result;
     }
};
int main() {
    string text, pattern;
    char choice;
     do {
         // Clear input buffers
         cin.clear();
         cin.ignore(numeric_limits<streamsize>::max(), '\n');
         // Print results
         cout << "\nSearch Results:" <<endl;
         cout << "Text: " << text <<endl;
         cout << "Pattern: " << pattern <<endl;
         if (occurrences.empty()) {
             cout << "Pattern not found in the text." << endl;
         }
         else {
              cout << "Pattern found at following starting indices:" <<endl;
              for (int index : occurrences) {
                  cout << index << " ";
              }
              cout << endl;
         }
     cout << "Thank you for using KMP Pattern Search!" << endl;
     return 0;
}
#include   <iostream>
#include   <string>
#include   <vector>
#include   <unordered_map>
#include   <memory>
#include   <limits>
class SuffixTreeNode {
public:
    unordered_map<char, shared_ptr<SuffixTreeNode>> children;
    shared_ptr<SuffixTreeNode> suffixLink;
    int start;
    int* end;
    int suffixIndex;
class SuffixTree {
private:
    string text;
    shared_ptr<SuffixTreeNode> root;
    shared_ptr<SuffixTreeNode> lastNewNode;
    shared_ptr<SuffixTreeNode> activeNode;
    int activeEdge;
    int activeLength;
    int remainingSuffixCount;
    int leafEnd;
    int* rootEnd;
    int size;
              if (currentChild == activeNode->children.end()) {
                  activeNode->children[text[activeEdge]] =
                      make_shared<SuffixTreeNode>(phase, &leafEnd);
                  if (lastNewNode != nullptr) {
                      lastNewNode->suffixLink = activeNode;
                      lastNewNode = nullptr;
                  }
              }
              else {
                  shared_ptr<SuffixTreeNode> next = currentChild->second;
                  if (walkDown(next))
                      continue;
                      activeLength++;
                      break;
                  }
activeNode->children[text[activeEdge]] = splitNode;
                  splitNode->children[text[phase]] =
                    make_shared<SuffixTreeNode>(phase, &leafEnd);
                next->start += activeLength;
                splitNode->children[text[next->start]] = next;
                if (lastNewNode != nullptr) {
                    lastNewNode->suffixLink = splitNode;
                }
                lastNewNode = splitNode;
            }
remainingSuffixCount--;
public:
    SuffixTree() {
        root = make_shared<SuffixTreeNode>();
        rootEnd = new int(-1);
        root->end = rootEnd;
        activeNode = root;
        size = 0;
    }
             if (child == currentNode->children.end()) {
                 cout << "Pattern not found in the text." << endl;
                 return;
             }
             if (patternIndex == pattern.length()) {
                 cout << "Pattern found in the text." << endl;
                 return;
             }
             currentNode = nextNode;
         }
     }
     void displayTree() {
         if (text.empty()) {
             cout << "Suffix tree not built. Build tree first." << endl;
             return;
         }
         cout << "Suffix Tree Structure:" << endl;
         printTree(root);
     }
     ~SuffixTree() {
         delete rootEnd;
     }
};
int main() {
    SuffixTree suffixTree;
    int choice;
    string input, pattern;
    while (true) {
        cout << "\n--- Suffix Tree Operations ---" << endl;
        cout << "1. Build Suffix Tree" << endl;
        cout << "2. Search Pattern" << endl;
        cout << "3. Display Suffix Tree" << endl;
        cout << "4. Exit" << endl;
        cout << "Enter your choice: ";
        cin >> choice;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
        switch (choice) {
            case 1:
                cout << "Enter the text to build suffix tree: ";
                getline(cin, input);
                suffixTree.buildSuffixTree(input);
                cout << "Suffix tree built successfully!" << endl;
                break;
            case 2:
                cout << "Enter pattern to search: ";
                getline(cin, pattern);
                suffixTree.searchPattern(pattern);
                break;
            case 3:
                suffixTree.displayTree();
                break;
            case 4:
                cout << "Exiting program..." << endl;
                return 0;
            default:
                cout << "Invalid choice. Please try again." << endl;
        }
    }
    return 0;
}
#include <iostream>
#include <string>
#include<limits>
#include <unordered_map>
using namespace std;
// A node in the suffix trie
class SuffixTrieNode {
public:
    unordered_map<char, SuffixTrieNode*> children;
     ~SuffixTrieNode() {
         for (auto& child : children) {
             delete child.second;
         }
     }
};
public:
    SuffixTrie() : root(new SuffixTrieNode()) {}
     void displayTrie() {
         cout << "Suffix Trie Structure:" << endl;
         printSuffixes(root, "");
     }
     ~SuffixTrie() {
         delete root;
     }
};
// Main function
int main() {
    SuffixTrie suffixTrie;
    string input, pattern;
    int choice;
     while (true) {
         cout << "\n--- Suffix Trie Operations ---" << endl;
         cout << "1. Build Suffix Trie" << endl;
         cout << "2. Search Pattern" << endl;
         cout << "3. Display Suffix Trie" << endl;
         cout << "4. Exit" << endl;
         cout << "Enter your choice: ";
         cin >> choice;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
         switch (choice) {
         case 1:
             cout << "Enter the text to build suffix trie: ";
             getline(cin, input);
             suffixTrie.buildSuffixTrie(input);
             cout << "Suffix trie built successfully!" << endl;
             break;
         case 2:
             cout << "Enter pattern to search: ";
             getline(cin, pattern);
             if (suffixTrie.searchPattern(pattern)) {
                 cout << "Pattern found in the text." << endl;
             } else {
                 cout << "Pattern not found in the text." << endl;
             }
             break;
         case 3:
             suffixTrie.displayTrie();
             break;
         case 4:
             cout << "Exiting program..." << endl;
             return 0;
        default:
            cout << "Invalid choice. Please try again." << endl;
        }
    }
    return 0;
}