diff --git a/DataStructures/Trie/implementation/Trie.cpp b/DataStructures/Trie/implementation/Trie.cpp new file mode 100644 index 0000000..654c598 --- /dev/null +++ b/DataStructures/Trie/implementation/Trie.cpp @@ -0,0 +1,78 @@ +// Implementation of Trie data structure in C++. + +/* + * Trie object will be instantiated and called as such: + * Trie* obj = new Trie(); + * obj->insert(word); + * bool param_0 = obj->search(word); + * bool param_0 = obj->startsWith(word); +*/ + +#include +#include +#include +using namespace std; + +// Create Trie node +class TrieNode { +public: + char val; + unordered_map children; + bool is_end; + + // Constructor + TrieNode(char val = '\0', bool is_end = false) : val(val), is_end(is_end) {} +}; + +class Trie { +private: + TrieNode* root; + +public: + // Create root node + Trie() { + root = new TrieNode(); + } + + // Insert a word into the Trie + void insert(const string& word) { + TrieNode* node = root; + + for (char c : word) { + if (node->children.find(c) == node->children.end()) { + node->children[c] = new TrieNode(c); + } + node = node->children[c]; + } + node->is_end = true; // Mark the end of a word + } + + // Search for a word in the Trie + bool search(const string& word) { + TrieNode* node = root; + + for (char c : word) { + if (node->children.find(c) == node->children.end()) { + return false; + } + node = node->children[c]; + } + + return node->is_end; + } + + // Check if a word in Trie starts with prefix + bool startsWith(const string& prefix) { + TrieNode* node = root; + + for (char c : prefix) { + if (node->children.find(c) == node->children.end()) { + return false; + } + node = node->children[c]; + } + + return true; + } +}; + diff --git a/DataStructures/Trie/implementation/Trie.java b/DataStructures/Trie/implementation/Trie.java new file mode 100644 index 0000000..6605e2e --- /dev/null +++ b/DataStructures/Trie/implementation/Trie.java @@ -0,0 +1,76 @@ +// Implementation of Trie data structure in java. + +/* + * Trie object will be instantiated and called as such: + * Trie obj = new Trie(); + * obj.insert(word); + * boolean param_0 = obj.search(word); + * boolean param_1 = obj.startsWith(word); +*/ + +// Create Trie node +class TrieNode { + public char val; + public boolean isEnd; + public TrieNode[] children; + + // Constructor + public TrieNode(char val) { + this.val = val; + this.isEnd = false; + this.children = new TrieNode[26]; + } +} + +class Trie { + private TrieNode root; + + // Create root node + public Trie() { + root = new TrieNode(' '); + } + + // Insert a word into the Trie + public void insert(String word) { + TrieNode node = root; + + for (char c : word.toCharArray()) { + int index = c - 'a'; + if (node.children[index] == null) { + node.children[index] = new TrieNode(c); + } + node = node.children[index]; + } + node.isEnd = true; // Mark the end of a word + } + + // Search for a word in the Trie + public boolean search(String word) { + TrieNode node = root; + + for (char c : word.toCharArray()) { + int index = c - 'a'; + if (node.children[index] == null) { + return false; + } + node = node.children[index]; + } + + return node.isEnd; + } + + // Check if a word in Trie starts with prefix + public boolean startsWith(String prefix) { + TrieNode node = root; + + for (char c : prefix.toCharArray()) { + int index = c - 'a'; + if (node.children[index] == null) { + return false; + } + node = node.children[index]; + } + + return true; + } +} diff --git a/DataStructures/Trie/implementation/Trie.py b/DataStructures/Trie/implementation/Trie.py new file mode 100644 index 0000000..822912e --- /dev/null +++ b/DataStructures/Trie/implementation/Trie.py @@ -0,0 +1,51 @@ +# Implementation of Trie data structure in python. + +# Trie object will be instantiated and called as such: +# obj = Trie() +# obj.insert(word) +# param_0 = obj.search(word) +# param_1 = obj.startsWith(prefix) + +class TrieNode: + def __init__(self, val='', is_end=False): + ''' Create a Trie node ''' + self.val = val + self.children = {} + self.is_end = is_end + +class Trie: + def __init__(self): + ''' Create the root node ''' + self.root = TrieNode() + + def insert(self, word: str) -> None: + ''' Insert word in Trie ''' + node = self.root + + for c in word: + if c not in node.children: + node.children[c] = TrieNode(c) + node = node.children[c] + + node.is_end = True + + def search(self, word: str) -> bool: + ''' Search for word in Trie ''' + node = self.root + + for c in word: + if c not in node.children: return False + node = node.children[c] + + return node.is_end + + def startsWith(self, prefix: str) -> bool: + ''' Check if a word in Trie starts with prefix ''' + node = self.root + + for c in prefix: + if c not in node.children: return False + node = node.children[c] + + return True + diff --git a/DataStructures/UnionFind/implementation/UnionFind.cpp b/DataStructures/UnionFind/implementation/UnionFind.cpp new file mode 100644 index 0000000..5fd38cc --- /dev/null +++ b/DataStructures/UnionFind/implementation/UnionFind.cpp @@ -0,0 +1,66 @@ +// Implementation of Union Find / Disjoint Set Union (DSU) in C++ + +/* + * DSU object will be instantiated and called as such: + * UnionFind uf(n); + * uf.unite(x, y); + * int parent = uf.findRootOf(x); + * bool connected = uf.isConnected(x, y); +*/ + +#include +using namespace std; + +class UnionFind { +private: + vector root; + vector rank; + int sets; + +public: + // Constructor to create n sets + UnionFind(int n) { + root.resize(n); + rank.resize(n, 1); + sets = n; + for (int i = 0; i < n; ++i) { + root[i] = i; + } + } + + // Find the root of x (with path compression) + int findRootOf(int x) { + if (root[x] != x) { + root[x] = findRootOf(root[x]); // Path compression + } + return root[x]; + } + + // Unite the sets containing x and y + void unite(int x, int y) { + int rootX = findRootOf(x); + int rootY = findRootOf(y); + + // If they are already in the same set, return + if (rootX == rootY) { + return; + } + + // Union by rank + if (rank[rootY] > rank[rootX]) { + root[rootX] = rootY; + rank[rootY] += rank[rootX]; + } else { + root[rootY] = rootX; + rank[rootX] += rank[rootY]; + } + + sets--; // Decrease number of sets + } + + // Check if x and y are connected (belong to the same set) + bool isConnected(int x, int y) { + return findRootOf(x) == findRootOf(y); + } +}; + diff --git a/DataStructures/UnionFind/implementation/UnionFind.java b/DataStructures/UnionFind/implementation/UnionFind.java new file mode 100644 index 0000000..df27888 --- /dev/null +++ b/DataStructures/UnionFind/implementation/UnionFind.java @@ -0,0 +1,63 @@ +// Implementation of Union Find / Disjoint Set Union (DSU) in java. + +/* + * DSU object will be instantiated and called as such: + * UnionFind uf = new UnionFind(n); + * uf.unite(x, y); + * int parent = uf.findRootOf(x); + * boolean connected = uf.isConnected(x, y); +*/ + +class UnionFind { + private int[] root; + private int[] rank; + private int sets; + + // Constructor to create n sets + public UnionFind(int n) { + root = new int[n]; + rank = new int[n]; + sets = n; + + for (int i = 0; i < n; i++) { + root[i] = i; + rank[i] = 1; + } + } + + // Find the root of x (with path compression) + public int findRootOf(int x) { + if (root[x] != x) { + root[x] = findRootOf(root[x]); // Path compression + } + return root[x]; + } + + // Unite the sets containing x and y + public void unite(int x, int y) { + int rootX = findRootOf(x); + int rootY = findRootOf(y); + + // If they are already in the same set, return + if (rootX == rootY) { + return; + } + + // Union by rank + if (rank[rootY] > rank[rootX]) { + root[rootX] = rootY; + rank[rootY] += rank[rootX]; + } else { + root[rootY] = rootX; + rank[rootX] += rank[rootY]; + } + + sets--; // Decrease number of sets + } + + // Check if x and y are connected (belong to the same set) + public boolean isConnected(int x, int y) { + return findRootOf(x) == findRootOf(y); + } +} + diff --git a/DataStructures/UnionFind/implementation/UnionFind.py b/DataStructures/UnionFind/implementation/UnionFind.py new file mode 100644 index 0000000..3032438 --- /dev/null +++ b/DataStructures/UnionFind/implementation/UnionFind.py @@ -0,0 +1,47 @@ +# Implementation of Union Find / Disjoint Set Union (DSU) in python + +# DSU object will be instantiated and called as such: +# obj = UnionFind(n) +# obj.unite(x, y) +# parent = obj.findRootOf(x) +# connected = obj.isConnected(x, y) + +class UnionFind: + def __init__(self, n): + ''' Create n sets ''' + self.root = [i for i in range(n)] + self.rank = [1] * n + self.sets = n + + def findRootOf(self, x): + ''' Find the root of x ''' + while self.root[x] != x: + # Path compression + self.root[x] = self.root[self.root[x]] + x = self.root[x] + return x + + def unite(self, x, y): + ''' Unite the sets of x and y ''' + rootX = self.findRootOf(x) + rootY = self.findRootOf(y) + + # Return if they belong from the same sets + if rootX == rootY: + return + + # Put the smaller set into the bigger set + if self.rank[rootY] > self.rank[rootX]: + self.root[rootX] = rootY + self.rank[rootY] += self.rank[rootX] + else: + self.root[rootY] = rootX + self.rank[rootX] += self.rank[rootY] + + # Decrement set count + self.sets -= 1 + + def isConnected(self, x, y): + ''' Check if x and y belong to the same set ''' + return self.findRootOf(x) == self.findRootOf(y) +