Skip to content

Commit e6bafa6

Browse files
Merge branch 'master' into cstdint
2 parents 3aa689c + db182d5 commit e6bafa6

File tree

5 files changed

+275
-112
lines changed

5 files changed

+275
-112
lines changed

DIRECTORY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
* [Searching Of Element In Dynamic Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/searching_of_element_in_dynamic_array.cpp)
120120
* [Shortest Common Supersequence](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/shortest_common_supersequence.cpp)
121121
* [Subset Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/subset_sum.cpp)
122+
* [Trapped Rainwater](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/trapped_rainwater.cpp)
122123
* [Tree Height](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/tree_height.cpp)
123124
* [Word Break](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/word_break.cpp)
124125

@@ -161,7 +162,7 @@
161162
* [Boruvkas Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/boruvkas_minimum_spanning_tree.cpp)
162163
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/dijkstra.cpp)
163164
* [Huffman](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/huffman.cpp)
164-
* [Jumpgame](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/jumpgame.cpp)
165+
* [Jump Game](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/jump_game.cpp)
165166
* [Knapsack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/knapsack.cpp)
166167
* [Kruskals Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/kruskals_minimum_spanning_tree.cpp)
167168
* [Prims Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/prims_minimum_spanning_tree.cpp)
Lines changed: 166 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,179 @@
1-
#include <iostream>
1+
#include <cassert> /// For std::assert
2+
#include <iostream> /// For std::cout
3+
#include <memory> /// For std::unique_ptr
4+
#include <stdexcept> /// For std::out_of_range
25

3-
int *stack;
4-
int stack_idx = 0, stack_size;
6+
/**
7+
* @namespace
8+
* @brief data_structures
9+
*/
10+
namespace data_structures {
11+
/**
12+
* @brief Class representation of a stack
13+
* @tparam T The type of the elements in the stack
14+
*/
15+
template <typename T>
16+
class Stack {
17+
private:
18+
std::unique_ptr<T[]> stack; ///< Smart pointer to the stack array
19+
int stackSize; ///< Maximum size of the stack
20+
int stackIndex; ///< Index pointing to the top element of the stack
521

6-
void push(int x) {
7-
if (stack_idx == stack_size) {
8-
std::cout << "\nOverflow";
9-
} else {
10-
stack[stack_idx++] = x;
22+
public:
23+
/**
24+
* @brief Constructs a new Stack object
25+
*
26+
* @param size Maximum size of the stack
27+
*/
28+
Stack(int size) : stackSize(size), stackIndex(-1), stack(new T[size]) {}
29+
30+
/**
31+
* @brief Checks if the stack is full
32+
*
33+
* @return true if the stack is full, false otherwise
34+
*/
35+
bool full() const { return stackIndex == stackSize - 1; }
36+
37+
/**
38+
* @brief Checks if the stack is empty
39+
* @return true if the stack is empty, false otherwise
40+
*/
41+
bool empty() const { return stackIndex == -1; }
42+
43+
/**
44+
* @brief Pushes an element onto the stack
45+
*
46+
* @param element Element to push onto the stack
47+
*/
48+
void push(T element) {
49+
if (full()) {
50+
throw std::out_of_range("Stack overflow");
51+
} else {
52+
stack[++stackIndex] = element;
53+
}
1154
}
12-
}
1355

14-
void pop() {
15-
if (stack_idx == 0) {
16-
std::cout << "\nUnderflow";
17-
} else {
18-
std::cout << "\n" << stack[--stack_idx] << " deleted";
56+
/**
57+
* @brief Pops an element from the stack
58+
*
59+
* @return The popped element
60+
* @throws std::out_of_range if the stack is empty
61+
*/
62+
T pop() {
63+
if (empty()) {
64+
throw std::out_of_range("Stack underflow");
65+
}
66+
return stack[stackIndex--];
67+
}
68+
69+
/**
70+
* @brief Displays all elements in the stack
71+
*/
72+
void show() const {
73+
for (int i = 0; i <= stackIndex; i++) {
74+
std::cout << stack[i] << "\n";
75+
}
1976
}
20-
}
2177

22-
void show() {
23-
for (int i = 0; i < stack_idx; i++) {
24-
std::cout << stack[i] << "\n";
78+
/**
79+
* @brief Displays the topmost element of the stack
80+
*
81+
* @return The topmost element of the stack
82+
* @throws std::out_of_range if the stack is empty
83+
*/
84+
T topmost() const {
85+
if (empty()) {
86+
throw std::out_of_range("Stack underflow");
87+
}
88+
return stack[stackIndex];
2589
}
26-
}
2790

28-
void topmost() { std::cout << "\nTopmost element: " << stack[stack_idx - 1]; }
29-
void bottom() { std::cout << "\nBottom element: " << stack[0]; } // If we need access to first element without using pop command
30-
int main() {
31-
std::cout << "\nEnter stack_size of stack : ";
32-
std::cin >> stack_size;
33-
stack = new int[stack_size];
34-
int ch, x;
35-
do {
36-
std::cout << "\n0. Exit";
37-
std::cout << "\n1. Push";
38-
std::cout << "\n2. Pop";
39-
std::cout << "\n3. Print";
40-
std::cout << "\n4. Print topmost element:";
41-
std::cout << "\n5. Print Bottom element:";
42-
std::cout << "\nEnter Your Choice : ";
43-
std::cin >> ch;
44-
if (ch == 1) {
45-
std::cout << "\nInsert : ";
46-
std::cin >> x;
47-
push(x);
48-
} else if (ch == 2) {
49-
pop();
50-
} else if (ch == 3) {
51-
show();
52-
} else if (ch == 4) {
53-
topmost();
54-
} else if(ch == 5) {
55-
bottom();
91+
/**
92+
* @brief Displays the bottom element of the stack
93+
*
94+
* @return The bottom element of the stack
95+
* @throws std::out_of_range if the stack is empty
96+
*/
97+
T bottom() const {
98+
if (empty()) {
99+
throw std::out_of_range("Stack underflow");
56100
}
57-
} while (ch != 0);
101+
return stack[0];
102+
}
103+
};
104+
} // namespace data_structures
105+
106+
/**
107+
* @brief Self-test implementations
108+
* @returns void
109+
*/
110+
static void test() {
111+
data_structures::Stack<int> stack(5);
112+
113+
// Test empty and full operations
114+
assert(stack.empty());
115+
assert(!stack.full());
58116

59-
delete[] stack;
117+
// Test pushing elements and checking topmost
118+
stack.push(10);
119+
assert(stack.topmost() == 10);
60120

121+
stack.push(20);
122+
assert(stack.topmost() == 20);
123+
124+
stack.push(30);
125+
stack.push(40);
126+
stack.push(50);
127+
assert(stack.full());
128+
129+
// Test stack overflow
130+
try {
131+
stack.push(60);
132+
} catch (const std::out_of_range& e) {
133+
assert(std::string(e.what()) == "Stack overflow");
134+
}
135+
136+
// Test popping elements
137+
assert(stack.pop() == 50);
138+
assert(stack.pop() == 40);
139+
assert(stack.pop() == 30);
140+
141+
// Check topmost and bottom elements
142+
assert(stack.topmost() == 20);
143+
assert(stack.bottom() == 10);
144+
145+
assert(stack.pop() == 20);
146+
assert(stack.pop() == 10);
147+
148+
assert(stack.empty());
149+
assert(!stack.full());
150+
151+
// Test stack underflow
152+
try {
153+
stack.pop();
154+
} catch (const std::out_of_range& e) {
155+
assert(std::string(e.what()) == "Stack underflow");
156+
}
157+
158+
try {
159+
stack.topmost();
160+
} catch (const std::out_of_range& e) {
161+
assert(std::string(e.what()) == "Stack underflow");
162+
}
163+
164+
try {
165+
stack.bottom();
166+
} catch (const std::out_of_range& e) {
167+
assert(std::string(e.what()) == "Stack underflow");
168+
}
169+
}
170+
171+
/**
172+
* @brief Main function
173+
* @returns 0 on exit
174+
*/
175+
int main() {
176+
test(); // run self-test implementations
177+
std::cout << "All tests passed!" << std::endl;
61178
return 0;
62179
}

others/iterative_tree_traversals.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,25 @@ std::vector<int64_t> BinaryTree::inOrderIterative(Node *root) {
180180
}
181181
return result;
182182
}
183+
void deleteAll(Node *root) {
184+
if (root) {
185+
std::stack<Node *> stack;
186+
stack.push(root);
187+
188+
while (!stack.empty()) {
189+
const Node *current = stack.top();
190+
stack.pop();
191+
192+
if (current->right) {
193+
stack.push(current->right);
194+
}
195+
if (current->left) {
196+
stack.push(current->left);
197+
}
198+
delete current;
199+
}
200+
}
201+
}
183202
} // namespace iterative_tree_traversals
184203
} // namespace others
185204

@@ -396,5 +415,7 @@ int main() {
396415
test6(binaryTree, root); // run inorder-iterative test on negative values
397416
std::cout << "\nIn-order test on-negative value Passed!" << std::endl;
398417

418+
deleteAll(root);
419+
399420
return 0;
400421
}

sorting/tim_sort.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
// C++ program to perform TimSort.
22
#include <algorithm>
3+
#include <cassert>
34
#include <iostream>
5+
#include <numeric>
46

57
const int RUN = 32;
68

79
// this function sorts array from left index to to right index which is of size
810
// atmost RUN
911
void insertionSort(int arr[], int left, int right) {
1012
for (int i = left + 1; i <= right; i++) {
11-
int temp = arr[i];
13+
const int temp = arr[i];
1214
int j = i - 1;
1315
while (arr[j] > temp && j >= left) {
1416
arr[j + 1] = arr[j];
@@ -21,7 +23,7 @@ void insertionSort(int arr[], int left, int right) {
2123
// merge function merges the sorted runs
2224
void merge(int arr[], int l, int m, int r) {
2325
// original array is broken in two parts, left and right array
24-
int len1 = m - l + 1, len2 = r - m;
26+
const int len1 = m - l + 1, len2 = r - m;
2527
int *left = new int[len1], *right = new int[len2];
2628
for (int i = 0; i < len1; i++) left[i] = arr[l + i];
2729
for (int i = 0; i < len2; i++) right[i] = arr[m + 1 + i];
@@ -74,8 +76,8 @@ void timSort(int arr[], int n) {
7476
for (int left = 0; left < n; left += 2 * size) {
7577
// find ending point of left sub array
7678
// mid+1 is starting point of right sub array
77-
int mid = left + size - 1;
78-
int right = std::min((left + 2 * size - 1), (n - 1));
79+
const int mid = std::min((left + size - 1), (n - 1));
80+
const int right = std::min((left + 2 * size - 1), (n - 1));
7981

8082
// merge sub array arr[left.....mid] & arr[mid+1....right]
8183
merge(arr, left, mid, right);
@@ -89,10 +91,29 @@ void printArray(int arr[], int n) {
8991
std::cout << std::endl;
9092
}
9193

94+
/**
95+
* @brief self-test implementation
96+
* @returns void
97+
*/
98+
void tests() {
99+
// Case: array of length 65
100+
constexpr int N = 65;
101+
int arr[N];
102+
103+
std::iota(arr, arr + N, 0);
104+
std::reverse(arr, arr + N);
105+
assert(!std::is_sorted(arr, arr + N));
106+
107+
timSort(arr, N);
108+
assert(std::is_sorted(arr, arr + N));
109+
}
110+
92111
// Driver program to test above function
93112
int main() {
113+
tests(); // run self test implementations
114+
94115
int arr[] = {5, 21, 7, 23, 19};
95-
int n = sizeof(arr) / sizeof(arr[0]);
116+
const int n = sizeof(arr) / sizeof(arr[0]);
96117
printf("Given Array is\n");
97118
printArray(arr, n);
98119

0 commit comments

Comments
 (0)