Interactive Implementation of DSC-13 Algorithms
#include <iostream>
#include <vector>
#include <random>
#include <algorithm>
class RandomizedQuickSort {
private:
int comparisons;
std::random_device rd;
std::mt19937 gen;
public:
RandomizedQuickSort() : comparisons(0), gen(rd()) {}
int quickSort(std::vector<int>& arr, int low, int high) {
comparisons = 0;
quickSortHelper(arr, low, high);
return comparisons;
}
private:
void quickSortHelper(std::vector<int>& arr, int low, int high) {
if (low < high) {
int pivot = randomizedPartition(arr, low, high);
quickSortHelper(arr, low, pivot - 1);
quickSortHelper(arr, pivot + 1, high);
}
}
int randomizedPartition(std::vector<int>& arr, int low, int high) {
// Randomly select pivot
std::uniform_int_distribution<int> dis(low, high);
int randomIndex = dis(gen);
std::swap(arr[randomIndex], arr[high]);
return partition(arr, low, high);
}
int partition(std::vector<int>& arr, int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j <= high - 1; j++) {
comparisons++; // Count comparison
if (arr[j] <= pivot) {
i++;
std::swap(arr[i], arr[j]);
}
}
std::swap(arr[i + 1], arr[high]);
return i + 1;
}
};
#include <iostream>
#include <vector>
#include <random>
class RandomizedSelect {
private:
std::random_device rd;
std::mt19937 gen;
public:
RandomizedSelect() : gen(rd()) {}
int select(std::vector<int>& arr, int k) {
return selectHelper(arr, 0, arr.size() - 1, k - 1);
}
private:
int selectHelper(std::vector<int>& arr, int low, int high, int k) {
if (low == high) return arr[low];
int pivot = randomizedPartition(arr, low, high);
if (k == pivot) {
return arr[pivot];
} else if (k < pivot) {
return selectHelper(arr, low, pivot - 1, k);
} else {
return selectHelper(arr, pivot + 1, high, k);
}
}
int randomizedPartition(std::vector<int>& arr, int low, int high) {
std::uniform_int_distribution<int> dis(low, high);
int randomIndex = dis(gen);
std::swap(arr[randomIndex], arr[high]);
return partition(arr, low, high);
}
int partition(std::vector<int>& arr, int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j <= high - 1; j++) {
if (arr[j] <= pivot) {
i++;
std::swap(arr[i], arr[j]);
}
}
std::swap(arr[i + 1], arr[high]);
return i + 1;
}
};
#include <iostream>
#include <vector>
#include <algorithm>
struct Edge {
int src, dest, weight;
bool operator<(const Edge& other) const {
return weight < other.weight;
}
};
class UnionFind {
private:
std::vector<int> parent, rank;
public:
UnionFind(int n) : parent(n), rank(n, 0) {
for (int i = 0; i < n; i++) {
parent[i] = i;
}
}
int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]); // Path compression
}
return parent[x];
}
bool unionSets(int x, int y) {
int px = find(x), py = find(y);
if (px == py) return false; // Already in same set
// Union by rank
if (rank[px] < rank[py]) {
parent[px] = py;
} else if (rank[px] > rank[py]) {
parent[py] = px;
} else {
parent[py] = px;
rank[px]++;
}
return true;
}
};
class KruskalMST {
public:
std::vector<Edge> findMST(std::vector<Edge>& edges, int vertices) {
std::vector<Edge> mst;
std::sort(edges.begin(), edges.end());
UnionFind uf(vertices);
for (const Edge& edge : edges) {
if (uf.unionSets(edge.src, edge.dest)) {
mst.push_back(edge);
if (mst.size() == vertices - 1) break;
}
}
return mst;
}
int getMSTWeight(const std::vector<Edge>& mst) {
int totalWeight = 0;
for (const Edge& edge : mst) {
totalWeight += edge.weight;
}
return totalWeight;
}
};
#include <iostream>
#include <vector>
#include <climits>
struct BellmanEdge {
int src, dest, weight;
BellmanEdge(int s, int d, int w) : src(s), dest(d), weight(w) {}
};
class BellmanFord {
public:
std::pair<std::vector<int>, bool> shortestPaths(
const std::vector<BellmanEdge>& edges, int vertices, int source) {
std::vector<int> distance(vertices, INT_MAX);
distance[source] = 0;
// Relax edges V-1 times
for (int i = 0; i < vertices - 1; i++) {
for (const BellmanEdge& edge : edges) {
if (distance[edge.src] != INT_MAX &&
distance[edge.src] + edge.weight < distance[edge.dest]) {
distance[edge.dest] = distance[edge.src] + edge.weight;
}
}
}
// Check for negative cycles
for (const BellmanEdge& edge : edges) {
if (distance[edge.src] != INT_MAX &&
distance[edge.src] + edge.weight < distance[edge.dest]) {
return {distance, false}; // Negative cycle detected
}
}
return {distance, true}; // No negative cycle
}
void printPaths(const std::vector<int>& distance, int source) {
std::cout << "Shortest distances from vertex " << source << ":n";
for (int i = 0; i < distance.size(); i++) {
std::cout << "To vertex " << i << ": ";
if (distance[i] == INT_MAX) {
std::cout << "INF";
} else {
std::cout << distance[i];
}
std::cout << "n";
}
}
};
#include <iostream>
#include <vector>
#include <algorithm>
class BTreeNode {
public:
std::vector<int> keys;
std::vector<BTreeNode*> children;
bool isLeaf;
int degree; // Minimum degree
BTreeNode(int deg, bool leaf) : degree(deg), isLeaf(leaf) {}
void insertNonFull(int key) {
int i = keys.size() - 1;
if (isLeaf) {
keys.push_back(0);
while (i >= 0 && keys[i] > key) {
keys[i + 1] = keys[i];
i--;
}
keys[i + 1] = key;
} else {
while (i >= 0 && keys[i] > key) {
i--;
}
i++;
if (children[i]->keys.size() == 2 * degree - 1) {
splitChild(i, children[i]);
if (keys[i] < key) {
i++;
}
}
children[i]->insertNonFull(key);
}
}
void splitChild(int index, BTreeNode* fullChild) {
int degree = fullChild->degree;
BTreeNode* newChild = new BTreeNode(degree, fullChild->isLeaf);
// Move half of the keys to new child
for (int j = 0; j < degree - 1; j++) {
newChild->keys.push_back(fullChild->keys[j + degree]);
}
if (!fullChild->isLeaf) {
for (int j = 0; j < degree; j++) {
newChild->children.push_back(fullChild->children[j + degree]);
}
}
// Move the middle key up
keys.insert(keys.begin() + index, fullChild->keys[degree - 1]);
children.insert(children.begin() + index + 1, newChild);
// Reduce the full child's size
fullChild->keys.resize(degree - 1);
if (!fullChild->isLeaf) {
fullChild->children.resize(degree);
}
}
bool search(int key) {
int i = 0;
while (i < keys.size() && key > keys[i]) {
i++;
}
if (i < keys.size() && key == keys[i]) {
return true;
}
if (isLeaf) {
return false;
}
return children[i]->search(key);
}
void traverse() {
int i;
for (i = 0; i < keys.size(); i++) {
if (!isLeaf) {
children[i]->traverse();
}
std::cout << " " << keys[i];
}
if (!isLeaf) {
children[i]->traverse();
}
}
};
class BTree {
private:
BTreeNode* root;
int degree;
public:
BTree(int deg) : degree(deg), root(nullptr) {}
void insert(int key) {
if (root == nullptr) {
root = new BTreeNode(degree, true);
root->keys.push_back(key);
} else {
if (root->keys.size() == 2 * degree - 1) {
BTreeNode* newRoot = new BTreeNode(degree, false);
newRoot->children.push_back(root);
newRoot->splitChild(0, root);
int i = 0;
if (newRoot->keys[0] < key) {
i++;
}
newRoot->children[i]->insertNonFull(key);
root = newRoot;
} else {
root->insertNonFull(key);
}
}
}
bool search(int key) {
return (root == nullptr) ? false : root->search(key);
}
void traverse() {
if (root != nullptr) {
root->traverse();
}
}
};
#include <iostream>
#include <memory>
struct TreeNode {
int data;
std::unique_ptr<TreeNode> left;
std::unique_ptr<TreeNode> right;
TreeNode(int val) : data(val), left(nullptr), right(nullptr) {}
};
class BinarySearchTree {
private:
std::unique_ptr<TreeNode> root;
public:
BinarySearchTree() : root(nullptr) {}
void insert(int value) {
root = insertHelper(std::move(root), value);
}
bool search(int value) {
return searchHelper(root.get(), value);
}
void inorderTraversal() {
std::cout << "Inorder: ";
inorderHelper(root.get());
std::cout << std::endl;
}
void preorderTraversal() {
std::cout << "Preorder: ";
preorderHelper(root.get());
std::cout << std::endl;
}
void postorderTraversal() {
std::cout << "Postorder: ";
postorderHelper(root.get());
std::cout << std::endl;
}
private:
std::unique_ptr<TreeNode> insertHelper(std::unique_ptr<TreeNode> node, int value) {
if (!node) {
return std::make_unique<TreeNode>(value);
}
if (value < node->data) {
node->left = insertHelper(std::move(node->left), value);
} else if (value > node->data) {
node->right = insertHelper(std::move(node->right), value);
}
return node;
}
bool searchHelper(TreeNode* node, int value) {
if (!node) {
return false;
}
if (value == node->data) {
return true;
} else if (value < node->data) {
return searchHelper(node->left.get(), value);
} else {
return searchHelper(node->right.get(), value);
}
}
void inorderHelper(TreeNode* node) {
if (node) {
inorderHelper(node->left.get());
std::cout << node->data << " ";
inorderHelper(node->right.get());
}
}
void preorderHelper(TreeNode* node) {
if (node) {
std::cout << node->data << " ";
preorderHelper(node->left.get());
preorderHelper(node->right.get());
}
}
void postorderHelper(TreeNode* node) {
if (node) {
postorderHelper(node->left.get());
postorderHelper(node->right.get());
std::cout << node->data << " ";
}
}
};
#include <iostream>
#include <vector>
#include <string>
class KMPAlgorithm {
public:
std::vector<int> computeLPS(const std::string& pattern) {
int m = pattern.length();
std::vector<int> lps(m, 0);
int len = 0;
int i = 1;
while (i < m) {
if (pattern[i] == pattern[len]) {
len++;
lps[i] = len;
i++;
} else {
if (len != 0) {
len = lps[len - 1];
} else {
lps[i] = 0;
i++;
}
}
}
return lps;
}
std::vector<int> search(const std::string& text, const std::string& pattern) {
int n = text.length();
int m = pattern.length();
std::vector<int> matches;
std::vector<int> lps = computeLPS(pattern);
int i = 0; // index for text
int j = 0; // index for pattern
while (i < n) {
if (pattern[j] == text[i]) {
i++;
j++;
}
if (j == m) {
matches.push_back(i - j);
j = lps[j - 1];
} else if (i < n && pattern[j] != text[i]) {
if (j != 0) {
j = lps[j - 1];
} else {
i++;
}
}
}
return matches;
}
void displayLPS(const std::string& pattern) {
std::vector<int> lps = computeLPS(pattern);
std::cout << "Pattern: " << pattern << std::endl;
std::cout << "LPS: ";
for (int val : lps) {
std::cout << val << " ";
}
std::cout << std::endl;
}
};
#include <iostream>
#include <unordered_map>
#include <string>
#include <vector>
class SuffixTreeNode {
public:
std::unordered_map<char, SuffixTreeNode*> children;
int start;
int* end;
int suffixIndex;
SuffixTreeNode(int start, int* end)
: start(start), end(end), suffixIndex(-1) {}
};
class SuffixTree {
private:
std::string text;
SuffixTreeNode* root;
int* globalEnd;
public:
SuffixTree(const std::string& str) : text(str + "$") {
globalEnd = new int(-1);
root = new SuffixTreeNode(-1, globalEnd);
buildSuffixTree();
}
void buildSuffixTree() {
int n = text.length();
for (int i = 0; i < n; i++) {
insertSuffix(i);
}
}
void insertSuffix(int suffixIndex) {
SuffixTreeNode* current = root;
for (int i = suffixIndex; i < text.length(); i++) {
char c = text[i];
if (current->children.find(c) == current->children.end()) {
// Create new leaf node
int* leafEnd = new int(text.length() - 1);
current->children[c] = new SuffixTreeNode(i, leafEnd);
current->children[c]->suffixIndex = suffixIndex;
return;
}
current = current->children[c];
// Check if we need to split an edge
int edgeLength = *(current->end) - current->start + 1;
int j = 0;
while (j < edgeLength && i + j < text.length() &&
text[current->start + j] == text[i + j]) {
j++;
}
if (j == edgeLength) {
i += j - 1;
continue;
}
// Split the edge
int* splitEnd = new int(current->start + j - 1);
SuffixTreeNode* splitNode = new SuffixTreeNode(current->start, splitEnd);
current->start += j;
splitNode->children[text[current->start]] = current;
if (i + j < text.length()) {
int* newLeafEnd = new int(text.length() - 1);
splitNode->children[text[i + j]] =
new SuffixTreeNode(i + j, newLeafEnd);
splitNode->children[text[i + j]]->suffixIndex = suffixIndex;
}
return;
}
}
bool search(const std::string& pattern) {
SuffixTreeNode* current = root;
int i = 0;
while (i < pattern.length()) {
char c = pattern[i];
if (current->children.find(c) == current->children.end()) {
return false;
}
current = current->children[c];
int edgeLength = *(current->end) - current->start + 1;
int j = 0;
while (j < edgeLength && i < pattern.length() &&
text[current->start + j] == pattern[i]) {
i++;
j++;
}
if (j < edgeLength && i < pattern.length()) {
return false;
}
}
return true;
}
void displaySuffixes() {
std::cout << "All suffixes of '" << text.substr(0, text.length()-1) << "':n";
for (int i = 0; i < text.length() - 1; i++) {
std::cout << i << ": " << text.substr(i, text.length()-1-i) << std::endl;
}
}
};