TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
inorder_successor_of_bst.cpp
Go to the documentation of this file.
1
36#include <cassert>
37#include <iostream>
38#include <vector>
39
45
51namespace inorder_traversal_of_bst {
52
56class Node {
57 public:
58 int64_t data;
61};
62
68Node *makeNode(int64_t data) {
69 Node *node = new Node();
70 node->data = data;
71 node->left = nullptr;
72 node->right = nullptr;
73 return node;
74}
75
82Node *Insert(Node *root, int64_t data) {
83 if (root == nullptr) {
84 root = makeNode(data);
85 } else if (data <= root->data) {
86 root->left = Insert(root->left, data);
87 } else {
88 root->right = Insert(root->right, data);
89 }
90 return root;
91}
92
100Node *getNode(Node *root, int64_t data) {
101 if (root == nullptr) {
102 return nullptr;
103 } else if (root->data == data) {
104 return root;
105 } else if (data > root->data) {
108 return getNode(root->right, data);
109 } else {
112 return getNode(root->left, data);
113 }
114}
115
122 if (root == nullptr) {
123 return root;
124 }
125 while (root->left != nullptr) {
126 root = root->left;
127 }
128 return root;
129}
130
136void printInorder(Node *root) {
137 if (root == nullptr) {
138 return;
139 }
140
141 printInorder(root->left);
142 std::cout << root->data << " ";
143 printInorder(root->right);
144}
145
155Node *makeBST(Node *root, const std::vector<int64_t> &data) {
156 for (int64_t values : data) {
157 root = Insert(root, values);
158 }
159 return root;
160}
161
177 Node *current = getNode(root, data);
178 if (current == nullptr) {
179 return nullptr;
180 }
181
182 // Case - 1
183 if (current->right != nullptr) {
184 return findMinNode(current->right);
185 }
186 // case - 2
187 else {
188 Node *successor = nullptr;
189 Node *ancestor = root;
190
191 while (ancestor != current && ancestor != nullptr) {
192 // This means my current node is in left of the root node
193 if (current->data < ancestor->data) {
194 successor = ancestor;
195 ancestor = ancestor->left; // keep going left
196 } else {
197 ancestor = ancestor->right;
198 }
199 }
200 return successor; // Nodes with maximum vales will not have a successor
201 }
202}
203
210void deallocate(Node *rootNode) {
211 if (rootNode == nullptr) {
212 return;
213 }
214 deallocate(rootNode->left);
215 deallocate(rootNode->right);
216 delete (rootNode);
217}
218
219} // namespace inorder_traversal_of_bst
220} // namespace operations_on_datastructures
221
226 private:
232 template <typename T>
233 void log(T msg) {
234 // It's just to avoid writing cout and endl
235 std::cout << "[TESTS] : ---> " << msg << std::endl;
236 }
237
238 public:
243 void runTests() {
244 log("Running Tests...");
245
246 testCase_1();
247 testCase_2();
248 testCase_3();
249
250 log("Test Cases over!");
251 std::cout << std::endl;
252 }
253
259 void testCase_1() {
261 *expectedOutput = nullptr;
262
263 log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
264 log("This is test case 1 : ");
265 log("Description:");
266 log(" EDGE CASE : Printing inorder successor for last node in the "
267 "BST, Output will be nullptr.");
268
270 nullptr;
271 std::vector<int64_t> node_data{
272 20, 3, 5, 6, 2, 23, 45, 78, 21};
273
274 root = operations_on_datastructures::inorder_traversal_of_bst::makeBST(
275 root,
276 node_data);
277
278 std::cout << "Inorder sequence is : ";
279 operations_on_datastructures::inorder_traversal_of_bst::printInorder(
280 root);
281 std::cout << std::endl;
282
284 *inorderSuccessor = operations_on_datastructures::
285 inorder_traversal_of_bst::getInorderSuccessor(
286 root, 78);
287
288 log("Checking assert expression...");
289 assert(inorderSuccessor == expectedOutput);
290 log("Assertion check passed!");
291
292 operations_on_datastructures::inorder_traversal_of_bst::deallocate(
293 root);
294
295 log("[PASS] : TEST CASE 1 PASS!");
296 log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
297 }
298
304 void testCase_2() {
305 const int expectedOutput = 21;
306
307 log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
308 log("This is test case 2 : ");
309
311 nullptr;
312 std::vector<int64_t> node_data{
313 20, 3, 5, 6, 2, 23, 45, 78, 21};
314
315 root = operations_on_datastructures::inorder_traversal_of_bst::makeBST(
316 root,
317 node_data);
318
319 std::cout << "Inorder sequence is : ";
320 operations_on_datastructures::inorder_traversal_of_bst::printInorder(
321 root);
322 std::cout << std::endl;
323
325 *inorderSuccessor = operations_on_datastructures::
326 inorder_traversal_of_bst::getInorderSuccessor(
327 root, 20);
328
329 log("Checking assert expression...");
330 assert(inorderSuccessor->data == expectedOutput);
331 log("Assertion check passed!");
332
333 operations_on_datastructures::inorder_traversal_of_bst::deallocate(
334 root);
335
336 log("[PASS] : TEST CASE 2 PASS!");
337 log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
338 }
339
345 void testCase_3() {
346 const int expectedOutput = 110;
347
348 log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
349 log("This is test case 3 : ");
350
352 nullptr;
353 std::vector<int64_t> node_data{
354 89, 67, 32, 56, 90, 123, 120,
355 110, 115, 6, 78, 7, 10};
356
357 root = operations_on_datastructures::inorder_traversal_of_bst::makeBST(
358 root,
359 node_data);
360
361 std::cout << "Inorder sequence is : ";
362 operations_on_datastructures::inorder_traversal_of_bst::printInorder(
363 root);
364 std::cout << std::endl;
365
367 *inorderSuccessor = operations_on_datastructures::
368 inorder_traversal_of_bst::getInorderSuccessor(
369 root, 90);
370
371 log("Checking assert expression...");
372 assert(inorderSuccessor->data == expectedOutput);
373 log("Assertion check passed!");
374
375 operations_on_datastructures::inorder_traversal_of_bst::deallocate(
376 root);
377
378 log("[PASS] : TEST CASE 3 PASS!");
379 log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
380 }
381};
382
387static void test() {
388 TestCases tc;
389 tc.runTests();
390}
391
398int main(int argc, char *argv[]) {
399 test(); // run self-test implementations
400
402 nullptr;
403 std::vector<int64_t> node_data{3, 4, 5,
404 89, 1, 2};
405
406 int64_t targetElement = 4;
407 root = operations_on_datastructures::inorder_traversal_of_bst::makeBST(
408 root, node_data);
409
411 *inorderSuccessor = operations_on_datastructures::
412 inorder_traversal_of_bst::getInorderSuccessor(root, targetElement);
413
414 std::cout << "In-order sequence is : ";
415 operations_on_datastructures::inorder_traversal_of_bst::printInorder(root);
416 std::cout << std::endl;
417
418 if (inorderSuccessor == nullptr) {
419 std::cout << "Inorder successor for last node is NULL" << std::endl;
420 } else {
421 std::cout << "Target element is : " << targetElement << std::endl;
422 std::cout << "Inorder successor for target element is : "
423 << inorderSuccessor->data << std::endl;
424 }
425
426 deallocate(root);
427
428 return 0;
429}
struct node { int data; int height; struct node *left; struct node *right;} node
for std::queue
Definition avltree.cpp:13
class encapsulating the necessary test cases
void log(T msg)
A function to print given message on console.
void testCase_2()
A test case which contains main list of 100 elements and sublist of 20.
void testCase_1()
A test case contains edge case, printing inorder successor of last node.
void testCase_3()
A test case which contains main list of 50 elements and sublist of 20.
void runTests()
Executes test cases.
A Node structure representing a single node in BST.
int main()
Main function.
int data[MAX]
test data
Node * makeBST(Node *root, const std::vector< int64_t > &data)
This function is used in test cases to quickly create BST containing large data instead of hard codin...
Node * getInorderSuccessor(Node *root, int64_t data)
Inorder successor of a node is the next node in inorder traversal of the Binary Tree....
void printInorder(Node *root)
Prints the BST in inorder traversal using recursion.
Node * findMinNode(Node *root)
Finds and return the minimum node in BST.
void deallocate(Node *rootNode)
This function clears the memory allocated to entire tree recursively. Its just for clean up the memor...
Node * makeNode(int64_t data)
Allocates a new node in heap for given data and returns it's pointer.
Node * getNode(Node *root, int64_t data)
Searches the given data in BST and returns the pointer to the node containing that data.
static void test()
Self-test implementations.