Skip to content

Commit ab907f2

Browse files
folder of set structured, not implemented
1 parent 80e3b85 commit ab907f2

File tree

12 files changed

+254
-0
lines changed

12 files changed

+254
-0
lines changed

Algorithms/Graphs Algorithms/graph.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#pragma once
2+
3+
#include <vector>
4+
#include <list>
5+
6+
class Graph
7+
{
8+
public:
9+
Graph(int V) : V(V)
10+
{
11+
adj = new std::list<int>[V];
12+
}
13+
14+
~Graph()
15+
{
16+
delete[] adj;
17+
}
18+
19+
void addEdge(int v, int w)
20+
{
21+
adj[v].push_back(w);
22+
}
23+
24+
std::list<int> getAdj(int v) const
25+
{
26+
return adj[v];
27+
}
28+
29+
int getV() const
30+
{
31+
return V;
32+
}
33+
34+
private:
35+
int V; // No. of vertices
36+
std::list<int> *adj; // Pointer to an array containing adjacency lists
37+
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#pragma once
2+
3+
#include <vector>
4+
#include <list>
5+
6+
class Graph
7+
{
8+
public:
9+
Graph(int V) : V(V)
10+
{
11+
adj = new std::list<std::pair<int, int>>[V];
12+
}
13+
14+
~Graph()
15+
{
16+
delete[] adj;
17+
}
18+
19+
void addEdge(int v, int w, int weight)
20+
{
21+
adj[v].push_back(std::make_pair(w, weight));
22+
}
23+
24+
std::list<std::pair<int, int>> getAdj(int v) const
25+
{
26+
return adj[v];
27+
}
28+
29+
int getV() const
30+
{
31+
return V;
32+
}
33+
34+
private:
35+
int V; // No. of vertices
36+
std::list<std::pair<int, int>> *adj; // Pointer to an array containing adjacency lists
37+
};

Data Structures/Sets/Set/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Set Implementation in C++
2+
3+
This project provides an implementation of the Set data structure in C++. The Set is a container that stores unique elements in no particular order.
4+
5+
## Set Implementation Details
6+
7+
Our Set data structure is implemented using a combination of a Hash Map (std::unordered_map) and a Vector of keys. This combination allows for efficient insert, delete, and find operations, while also maintaining the insertion order of the elements.
8+
9+
## Basic Operations of a Set
10+
11+
This implementation supports the following basic operations:
12+
* Insert: Add an element to the set.
13+
* Remove: Remove an element from the set.
14+
* Contains: Check if an element is in the set.
15+
* Size: Returns the number of elements in the set.
16+
17+
## Alternative Set Implementations
18+
19+
Sets can be implemented with different data structures, each with its own trade-offs:
20+
21+
* **Vector**: A simple array or vector can be used to implement a set. The elements can be kept sorted or unsorted. The advantage of using a vector is its simplicity and support for random access. However, insertion and deletion operations can be slow, especially for large sets.
22+
23+
* **Linked List**: A linked list can also be used to implement a set. This provides efficient insertion and deletion operations but slower search times.
24+
25+
* **Hashmap / Hashtable**: A hashmap can provide average-case constant time, O(1), for insert, delete, and find operations. This is a significant improvement over vector and linked list implementations. However, hashmaps do not preserve any order of elements, and they can be more space-inefficient due to the need to handle potential hash collisions.
26+
27+
* **Balanced Binary Search Tree (e.g., AVL tree, Red-Black tree)**: These can provide a good trade-off between the speed of operations and the preservation of the order of elements. Insertion, deletion, and find operations can all be performed in O(log n) time, and they can also provide ordered traversal of elements.
28+
29+
* **Bit Vector**: If the set elements are from a limited integer range, a bit vector can be used. Each bit in the bit vector represents whether an element is in the set.
30+
31+
* **Trie**: If the set elements are strings, a Trie can be an efficient data structure for a set. A Trie can check if a string is in a set in O(m) time, where m is the length of the string. This can be faster than other data structures if the strings are long and the set is large.

Data Structures/Sets/Set/main.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <iostream>
2+
#include "set.h"
3+
#include "testSet.h"
4+
5+
void interactWithUser() {
6+
Set set;
7+
char option = ' ';
8+
int val = 0;
9+
10+
while (true) {
11+
std::cout << "Please choose an option (i = insert, r = remove, c = contains, s = size, q = quit): ";
12+
std::cin >> option;
13+
switch (option) {
14+
case 'i':
15+
std::cout << "Enter a value to insert: ";
16+
std::cin >> val;
17+
set.insert(val);
18+
break;
19+
case 'r':
20+
std::cout << "Enter a value to remove: ";
21+
std::cin >> val;
22+
set.remove(val);
23+
break;
24+
case 'c':
25+
std::cout << "Enter a value to check: ";
26+
std::cin >> val;
27+
if (set.contains(val))
28+
std::cout << "The set contains " << val << ".\n";
29+
else
30+
std::cout << "The set does not contain " << val << ".\n";
31+
break;
32+
case 's':
33+
std::cout << "The set contains " << set.size() << " elements.\n";
34+
break;
35+
case 'q':
36+
return;
37+
default:
38+
std::cout << "Unknown option: " << option << '\n';
39+
}
40+
}
41+
}
42+
43+
int main() {
44+
run_tests();
45+
interactWithUser();
46+
return 0;
47+
}

Data Structures/Sets/Set/makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Makefile
2+
all: main
3+
4+
main: main.cpp set.cpp testSet.cpp
5+
g++ -o main main.cpp set.cpp testSet.cpp

Data Structures/Sets/Set/set.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include "set.h"
2+
3+
Set::Set() {}
4+
5+
Set::~Set() {}
6+
7+
bool Set::insert(int val) {
8+
// implementation goes here
9+
}
10+
11+
bool Set::remove(int val) {
12+
// implementation goes here
13+
}
14+
15+
bool Set::contains(int val) {
16+
// implementation goes here
17+
}
18+
19+
std::size_t Set::size() const {
20+
// implementation goes here
21+
}

Data Structures/Sets/Set/set.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
#include <vector>
3+
#include <unordered_map>
4+
5+
class Set {
6+
std::vector<int> keys;
7+
std::unordered_map<int, bool> hash_map;
8+
9+
public:
10+
Set();
11+
~Set();
12+
13+
bool insert(int val);
14+
bool remove(int val);
15+
bool contains(int val);
16+
std::size_t size() const;
17+
};

Data Structures/Sets/Set/testSet.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include "set.h"
2+
#include "testSet.h"
3+
#include <cassert>
4+
5+
void test_insert_and_contains() {
6+
Set set;
7+
assert(set.insert(1) == true);
8+
assert(set.contains(1) == true);
9+
assert(set.insert(1) == false);
10+
assert(set.contains(1) == true);
11+
}
12+
13+
void test_remove() {
14+
Set set;
15+
assert(set.insert(1) == true);
16+
assert(set.remove(1) == true);
17+
assert(set.contains(1) == false);
18+
assert(set.remove(1) == false);
19+
}
20+
21+
void test_size() {
22+
Set set;
23+
assert(set.size() == 0);
24+
assert(set.insert(1) == true);
25+
assert(set.size() == 1);
26+
assert(set.insert(2) == true);
27+
assert(set.size() == 2);
28+
assert(set.remove(1) == true);
29+
assert(set.size() == 1);
30+
}
31+
32+
void run_tests() {
33+
test_insert_and_contains();
34+
test_remove();
35+
test_size();
36+
}

Data Structures/Sets/Set/testSet.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#pragma once
2+
3+
void run_tests();
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Adapter Design Pattern
2+
3+
The Adapter pattern is a structural design pattern that allows objects with incompatible interfaces to collaborate. It's often used when you want to make your own classes work with others without modifying their source code.
4+
5+
## Structure
6+
7+
The Adapter pattern involves a single class, the 'Adapter', which is responsible for communication between the existing ('Adaptee') and the new ('Target') systems.
8+
9+
1. **Target**: This is the domain-specific interface that Client is expected to work with.
10+
2. **Adapter**: This adapts the interface Adaptee to the Target interface.
11+
3. **Adaptee**: This is the existing interface that needs adapting.
12+
4. **Client**: This collaborates with objects conforming to the Target interface.
13+
14+
## When to use
15+
16+
Use the Adapter pattern when you want to use some existing class, but its interface isn’t compatible with the rest of your code. The Adapter pattern lets you create a middle-layer class that serves as a translator between your code and a legacy class, a 3rd-party class or any other class with a weird interface.
17+
18+
## Example
19+
20+
An example can be a card reader acting as an adapter between a memory card and a laptop. The laptop's USB interface is not compatible with the memory card's interface. Therefore, the card reader adapts the memory card's interface to the laptop's interface.

0 commit comments

Comments
 (0)