Skip to content

Commit 7ecd3db

Browse files
authored
Merge branch 'master' into duval
2 parents 83b9e10 + 0ecb6bd commit 7ecd3db

File tree

12 files changed

+538
-114
lines changed

12 files changed

+538
-114
lines changed

DIRECTORY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* [Count Of Set Bits](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/count_of_set_bits.cpp)
2020
* [Count Of Trailing Ciphers In Factorial N](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/count_of_trailing_ciphers_in_factorial_n.cpp)
2121
* [Find Non Repeating Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/find_non_repeating_number.cpp)
22+
* [Gray Code](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/gray_code.cpp)
2223
* [Hamming Distance](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/hamming_distance.cpp)
2324
* [Next Higher Number With Same Number Of Set Bits](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/next_higher_number_with_same_number_of_set_bits.cpp)
2425
* [Power Of 2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/power_of_2.cpp)
@@ -161,6 +162,7 @@
161162
## Greedy Algorithms
162163
* [Boruvkas Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/boruvkas_minimum_spanning_tree.cpp)
163164
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/dijkstra.cpp)
165+
* [Gale Shapley](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/gale_shapley.cpp)
164166
* [Huffman](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/huffman.cpp)
165167
* [Jump Game](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/jump_game.cpp)
166168
* [Knapsack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/knapsack.cpp)
@@ -377,6 +379,7 @@
377379
* [Pigeonhole Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/pigeonhole_sort.cpp)
378380
* [Quick Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/quick_sort.cpp)
379381
* [Quick Sort 3](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/quick_sort_3.cpp)
382+
* [Quick Sort Iterative](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/quick_sort_iterative.cpp)
380383
* [Radix Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/radix_sort.cpp)
381384
* [Radix Sort2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/radix_sort2.cpp)
382385
* [Random Pivot Quick Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/random_pivot_quick_sort.cpp)

bit_manipulation/gray_code.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/**
2+
* @brief Program to generate n-bit [Gray
3+
* code](https://en.wikipedia.org/wiki/Gray_code)
4+
*
5+
* @details
6+
* Gray code is a binary numeral system
7+
* where consecutive values differ in exactly 1 bit.
8+
* The following code offers one of many possible Gray codes
9+
* given some pre-determined number of bits.
10+
*/
11+
12+
#include <bitset> /// for gray code representation
13+
#include <cassert> /// for assert
14+
#include <iostream> /// for IO operations
15+
#include <vector> /// for vector data structure
16+
17+
/**
18+
* @namespace bit_manipulation
19+
* @brief Bit manipulation algorithms
20+
*/
21+
namespace bit_manipulation {
22+
/**
23+
* @namespace gray_code
24+
* @brief Generate n-bit Gray code
25+
*/
26+
namespace gray_code {
27+
/**
28+
* @brief The main function to generate n-bit Gray code
29+
*
30+
* @param n Number of bits
31+
* @return A vector that stores the n-bit Gray code
32+
*/
33+
std::vector<std::bitset<32>> gray_code_generation(int n) {
34+
std::vector<std::bitset<32>> gray_code = {}; // Initialise empty vector
35+
36+
// No Gray codes for non-positive values of n
37+
if (n <= 0) {
38+
return gray_code;
39+
}
40+
41+
int total_codes = 1 << n; // Number of n-bit gray codes
42+
43+
for (int i = 0; i < total_codes; i++) {
44+
int gray_num = i ^ (i >> 1); // Gray code formula
45+
gray_code.push_back(std::bitset<32>(gray_num)); // Store the value
46+
}
47+
48+
return gray_code;
49+
}
50+
} // namespace gray_code
51+
} // namespace bit_manipulation
52+
53+
/**
54+
* @brief Self-test implementation
55+
*
56+
* @returns void
57+
*/
58+
static void test() {
59+
std::vector<std::bitset<32>> gray_code_negative_1 = {};
60+
61+
std::vector<std::bitset<32>> gray_code_0 = {};
62+
63+
std::vector<std::bitset<32>> gray_code_1 = {
64+
std::bitset<32>(0), std::bitset<32>(1)
65+
};
66+
67+
std::vector<std::bitset<32>> gray_code_2 = {
68+
std::bitset<32>(0), std::bitset<32>(1), std::bitset<32>(3), std::bitset<32>(2)
69+
};
70+
71+
std::vector<std::bitset<32>> gray_code_3 = {
72+
std::bitset<32>(0), std::bitset<32>(1), std::bitset<32>(3), std::bitset<32>(2),
73+
std::bitset<32>(6), std::bitset<32>(7), std::bitset<32>(5), std::bitset<32>(4)
74+
};
75+
76+
std::vector<std::bitset<32>> gray_code_4 = {
77+
std::bitset<32>(0), std::bitset<32>(1), std::bitset<32>(3), std::bitset<32>(2),
78+
std::bitset<32>(6), std::bitset<32>(7), std::bitset<32>(5), std::bitset<32>(4),
79+
std::bitset<32>(12), std::bitset<32>(13), std::bitset<32>(15), std::bitset<32>(14),
80+
std::bitset<32>(10), std::bitset<32>(11), std::bitset<32>(9), std::bitset<32>(8)
81+
};
82+
83+
std::vector<std::bitset<32>> gray_code_5 = {
84+
std::bitset<32>(0), std::bitset<32>(1), std::bitset<32>(3), std::bitset<32>(2),
85+
std::bitset<32>(6), std::bitset<32>(7), std::bitset<32>(5), std::bitset<32>(4),
86+
std::bitset<32>(12), std::bitset<32>(13), std::bitset<32>(15), std::bitset<32>(14),
87+
std::bitset<32>(10), std::bitset<32>(11), std::bitset<32>(9), std::bitset<32>(8),
88+
std::bitset<32>(24), std::bitset<32>(25), std::bitset<32>(27), std::bitset<32>(26),
89+
std::bitset<32>(30), std::bitset<32>(31), std::bitset<32>(29), std::bitset<32>(28),
90+
std::bitset<32>(20), std::bitset<32>(21), std::bitset<32>(23), std::bitset<32>(22),
91+
std::bitset<32>(18), std::bitset<32>(19), std::bitset<32>(17), std::bitset<32>(16)
92+
};
93+
94+
// invalid values for n
95+
assert(bit_manipulation::gray_code::gray_code_generation(-1) == gray_code_negative_1);
96+
assert(bit_manipulation::gray_code::gray_code_generation(0) == gray_code_0);
97+
98+
// valid values for n
99+
assert(bit_manipulation::gray_code::gray_code_generation(1) == gray_code_1);
100+
assert(bit_manipulation::gray_code::gray_code_generation(2) == gray_code_2);
101+
assert(bit_manipulation::gray_code::gray_code_generation(3) == gray_code_3);
102+
assert(bit_manipulation::gray_code::gray_code_generation(4) == gray_code_4);
103+
assert(bit_manipulation::gray_code::gray_code_generation(5) == gray_code_5);
104+
}
105+
106+
/**
107+
* @brief Main function
108+
* @returns 0 on exit
109+
*/
110+
int main() {
111+
test(); //Run self-test implementation
112+
return 0;
113+
}

data_structures/circular_queue_using_linked_list.cpp

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,65 @@ struct node {
55
struct node* next;
66
};
77
class Queue {
8-
node* front=nullptr;
9-
node* rear=nullptr;
8+
node* front = nullptr;
9+
node* rear = nullptr;
1010

11-
public:
12-
Queue() = default;
11+
Queue(const Queue&) = delete;
12+
Queue& operator=(const Queue&) = delete;
13+
14+
public:
15+
Queue() = default;
16+
~Queue() {
17+
while (front) {
18+
dequeue();
19+
}
20+
}
21+
22+
private:
1323
void createNode(int val) {
1424
auto* nn = new node;
1525
nn->data = val;
1626
nn->next = nullptr;
1727
front = nn;
1828
rear = nn;
1929
}
30+
31+
public:
2032
void enqueue(int val) {
2133
if (front == nullptr || rear == nullptr) {
2234
createNode(val);
23-
}
24-
else {
25-
node* nn;
26-
nn = new node;
35+
} else {
36+
node* nn = new node;
2737
nn->data = val;
2838
rear->next = nn;
2939
nn->next = front;
3040
rear = nn;
3141
}
3242
}
3343
void dequeue() {
34-
node* n;
35-
n = front;
36-
if (n) {
44+
if (front == nullptr) {
45+
return;
46+
}
47+
const node* const n = front;
48+
if (front == rear) {
49+
front = nullptr;
50+
rear = nullptr;
51+
} else {
3752
front = front->next;
38-
delete n;
53+
rear->next = front;
3954
}
55+
delete n;
4056
}
4157
void traverse() {
42-
node* ptr;
43-
ptr = front;
44-
if (ptr) {
45-
do {
46-
std::cout << ptr->data << " ";
47-
ptr = ptr->next;
48-
} while (ptr != rear->next);
49-
std::cout << front->data << std::endl;
58+
if (front == nullptr) {
59+
return;
5060
}
61+
const node* ptr = front;
62+
do {
63+
std::cout << ptr->data << ' ';
64+
ptr = ptr->next;
65+
} while (ptr != front);
66+
std::cout << '\n';
5167
}
5268
};
5369
int main(void) {

data_structures/morrisinorder.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,21 @@ void morrisInorder(Btree *root) {
8181
}
8282
}
8383

84+
void deleteAll(const Btree *const root) {
85+
if (root) {
86+
deleteAll(root->left);
87+
deleteAll(root->right);
88+
delete root;
89+
}
90+
}
91+
8492
int main() {
8593
// Testing morrisInorder funtion
8694
Btree *root = NULL;
8795
int i;
8896
for (i = 1; i <= 7; i++) insert(&root, i);
8997
cout << "Morris Inorder: ";
9098
morrisInorder(root);
99+
deleteAll(root);
91100
return 0;
92101
}
Lines changed: 70 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,81 @@
1-
/** Print all the Catalan numbers from 0 to n, n being the user input.
2-
3-
* A Catalan number satifies the following two properties:
4-
* C(0) = C(1) = 1; C(n) = sum(C(i).C(n-i-1)), from i = 0 to n-1
1+
/**
2+
* @file
3+
* @brief Provides utilities to compute Catalan numbers using dynamic
4+
programming.
5+
* A Catalan numbers satisfy these recurrence relations:
6+
* C(0) = C(1) = 1; C(n) = sum(C(i).C(n-i-1)), for i = 0 to n-1
57
* Read more about Catalan numbers here:
68
https://en.wikipedia.org/wiki/Catalan_number
9+
https://oeis.org/A000108/
710
*/
811

9-
#include <iostream>
10-
using namespace std;
11-
12-
int *cat; // global array to hold catalan numbers
13-
14-
unsigned long int catalan_dp(int n) {
15-
/** Using the tabulation technique in dynamic programming,
16-
this function computes the first `n+1` Catalan numbers
17-
18-
Parameter
19-
---------
20-
n: The number of catalan numbers to be computed.
12+
#include <cassert> /// for assert
13+
#include <cstdint> /// for std::uint64_t
14+
#include <cstdlib> /// for std::size_t
15+
#include <numeric> /// for std::transform_reduce
16+
#include <vector> /// for std::vector
2117

22-
Returns
23-
-------
24-
cat[n]: An array containing the first `n+1` Catalan numbers
25-
*/
26-
27-
// By definition, the first two Catalan numbers are 1
28-
cat[0] = cat[1] = 1;
29-
30-
// Compute the remaining numbers from index 2 to index n, using tabulation
31-
for (int i = 2; i <= n; i++) {
32-
cat[i] = 0;
33-
for (int j = 0; j < i; j++)
34-
cat[i] += cat[j] * cat[i - j - 1]; // applying the definition here
18+
/**
19+
* @brief computes and caches Catalan numbers
20+
*/
21+
class catalan_numbers {
22+
using value_type = std::uint64_t;
23+
std::vector<value_type> known{1, 1};
24+
25+
value_type compute_next() {
26+
return std::transform_reduce(known.begin(), known.end(), known.rbegin(),
27+
static_cast<value_type>(), std::plus<>(),
28+
std::multiplies<>());
3529
}
3630

37-
// Return the result
38-
return cat[n];
39-
}
40-
41-
int main(int argc, char *argv[]) {
42-
int n;
43-
cout << "Enter n: ";
44-
cin >> n;
45-
46-
cat = new int[n + 1];
47-
48-
cout << "Catalan numbers from 0 to " << n << " are:\n";
49-
for (int i = 0; i <= n; i++) {
50-
cout << "catalan (" << i << ") = " << catalan_dp(i) << endl;
51-
// NOTE: Since `cat` is a global array, calling `catalan_dp`
52-
// repeatedly will not recompute the the values already computed
53-
// as in case of pre-computed values, the array will simply return them,
54-
// instead of recomputing them.
31+
void add() { known.push_back(this->compute_next()); }
32+
33+
public:
34+
/**
35+
* @brief computes the n-th Catalan number and updates the cache.
36+
* @return the n-th Catalan number
37+
*/
38+
value_type get(std::size_t n) {
39+
while (known.size() <= n) {
40+
this->add();
41+
}
42+
return known[n];
5543
}
56-
57-
return 0;
44+
};
45+
46+
void test_catalan_numbers_up_to_20() {
47+
// data verified with https://oeis.org/A000108/
48+
catalan_numbers cn;
49+
assert(cn.get(0) == 1ULL);
50+
assert(cn.get(1) == 1ULL);
51+
assert(cn.get(2) == 2ULL);
52+
assert(cn.get(3) == 5ULL);
53+
assert(cn.get(4) == 14ULL);
54+
assert(cn.get(5) == 42ULL);
55+
assert(cn.get(6) == 132ULL);
56+
assert(cn.get(7) == 429ULL);
57+
assert(cn.get(8) == 1430ULL);
58+
assert(cn.get(9) == 4862ULL);
59+
assert(cn.get(10) == 16796ULL);
60+
assert(cn.get(11) == 58786ULL);
61+
assert(cn.get(12) == 208012ULL);
62+
assert(cn.get(13) == 742900ULL);
63+
assert(cn.get(14) == 2674440ULL);
64+
assert(cn.get(15) == 9694845ULL);
65+
assert(cn.get(16) == 35357670ULL);
66+
assert(cn.get(17) == 129644790ULL);
67+
assert(cn.get(18) == 477638700ULL);
68+
assert(cn.get(19) == 1767263190ULL);
69+
assert(cn.get(20) == 6564120420ULL);
5870
}
5971

60-
/** Sample Test Case:
61-
62-
$ cd "Dynamic Programming"
63-
$ g++ Catalan-Numbers.cpp
64-
$ ./a.exe
65-
66-
Enter n: 5
67-
Catalan numbers from 0 to 5 are:
68-
catalan (0) = 1
69-
catalan (1) = 1
70-
catalan (2) = 2
71-
catalan (3) = 5
72-
catalan (4) = 14
73-
catalan (5) = 42
72+
void test_catalan_numbers_25() {
73+
// data verified with https://oeis.org/A000108/
74+
catalan_numbers cn;
75+
assert(cn.get(25) == 4861946401452ULL);
76+
}
7477

75-
*/
78+
int main() {
79+
test_catalan_numbers_up_to_20();
80+
test_catalan_numbers_25();
81+
}

0 commit comments

Comments
 (0)