Skip to content
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.

Commit

Permalink
add inorder and postorder traversal for cpp (#951)
Browse files Browse the repository at this point in the history
  • Loading branch information
gaurovgiri authored Nov 12, 2023
1 parent 7d8517d commit c827c50
Show file tree
Hide file tree
Showing 3 changed files with 325 additions and 0 deletions.
160 changes: 160 additions & 0 deletions C++/Data Structure/Trees/Inorder_traversal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#include <iostream>
#include <stack>
#include <vector>

using namespace std;

// Every node of the binary tree is represented by a 'node' data type
struct node
{
int key_value; // Value the node holds
node *left; // Address of its left child
node *right; // Address of its right child
};

class binaryTree
{
private:
node *root;
void insertKey(int key, node *leaf);
void inOrderTraversal_recursive(node *leaf);

public:
binaryTree();
void insertKeys(vector<int> keys);
void insertKey(int key);
void inOrderTraversal_recursive();
void inOrderTraversal_iterative();
};

// Constructor. Initializes root to NULL.
binaryTree::binaryTree()
{
root = NULL;
}

// Accepts a vector and calls insertKey(int) iteratively.
void binaryTree::insertKeys(vector<int> keys)
{
int len = keys.size();
for (int i = 0; i < len; i++)
{
insertKey(keys[i]);
}
}

// When called for the first time (when root IS initialized as NULL), insertKey(int)
// initializes root to point to a node data type. This node data type gets its key_value
// as the key (argument) and child nodes as NULL.
// For all calls other than the first time, it further calls insertKey(int, node*).
void binaryTree::insertKey(int key)
{
if (root != NULL)
{
insertKey(key, root);
}
else
{
root = new node;
root->key_value = key;
root->left = NULL;
root->right = NULL;
}
}

// Inserts the key, such that the tree follows the definition of a binary tree.
// The function traverses down the tree starting from the root to find a suitable position.
// If the key is less than the key_value at a node, the function calls itself with its left subtree.
// If the key is greater than or equal to the key_value at a node, the function calls itself with its right subtree.
// When it reaches a suitable place, it creates a new node. This node gets key_value as the key and child nodes as NULL.
void binaryTree::insertKey(int key, node *leaf)
{
if (key < leaf->key_value)
{
if (leaf->left != NULL)
{
insertKey(key, leaf->left);
}
else
{
leaf->left = new node;
leaf->left->key_value = key;
leaf->left->left = NULL;
leaf->left->right = NULL;
}
}
else if (key >= leaf->key_value)
{
if (leaf->right != NULL)
{
insertKey(key, leaf->right);
}
else
{
leaf->right = new node;
leaf->right->key_value = key;
leaf->right->left = NULL;
leaf->right->right = NULL;
}
}
}

// Calls inOrderTraversal_recursive, a private member-function.
void binaryTree::inOrderTraversal_recursive()
{
cout << "InOrderTraversal (recursive): ";
inOrderTraversal_recursive(root);
cout << endl;
}

// For a particular node, the function prints its key_value and recursively calls
// its left and right subtrees (in that order).
void binaryTree::inOrderTraversal_recursive(node *leaf)
{
if (leaf != NULL)
{
inOrderTraversal_recursive(leaf->left);
cout << leaf->key_value << " ";
inOrderTraversal_recursive(leaf->right);
}
}

// The iterative in-order traversal function.
void binaryTree::inOrderTraversal_iterative()
{
cout << "InOrderTraversal (iterative): ";
if (root == NULL)
return;
stack<node *> nodeAddr;
node *currentNode = root;

while (currentNode != NULL || !nodeAddr.empty())
{
while (currentNode != NULL)
{
nodeAddr.push(currentNode);
currentNode = currentNode->left;
}
if (!nodeAddr.empty())
{
currentNode = nodeAddr.top();
nodeAddr.pop();
cout << currentNode->key_value << " ";
currentNode = currentNode->right;
}
}
}

int main()
{
binaryTree Tree;
vector<int> elements = {25, 15, 50, 10, 22, 35, 70, 4, 12, 18, 24, 31, 44, 66, 80};
Tree.insertKeys(elements);

Tree.inOrderTraversal_recursive(); // Expected: 4 10 12 15 18 22 24 25 31 35 44 50 66 70 80
Tree.inOrderTraversal_iterative(); // Expected: 4 10 12 15 18 22 24 25 31 35 44 50 66 70 80

cout << endl;

return 0;
}
165 changes: 165 additions & 0 deletions C++/Data Structure/Trees/PostOrder_traversal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#include <iostream>
#include <stack>
#include <vector>
using namespace std;

// Every node of the binary tree is represented by a 'node' data type
struct node
{
int key_value; // Value the node holds
node *left; // Address of its left child
node *right; // Address of its right child
};

class binaryTree
{
private:
node *root;
void insertKey(int key, node *leaf);
void postOrderTraversal_recursive(node *leaf);

public:
binaryTree();
void insertKeys(vector<int> keys);
void insertKey(int key);
void postOrderTraversal_recursive();
void postOrderTraversal_iterative();
};

// Constructor. Initializes root to NULL.
binaryTree::binaryTree()
{
root = NULL;
}

// Accepts a vector and calls insertKey(int) iteratively.
void binaryTree::insertKeys(vector<int> keys)
{
int len = keys.size();
for (int i = 0; i < len; i++)
{
insertKey(keys[i]);
}
}

// When called for the first time (when root IS initialized as NULL), insertKey(int)
// initializes root to point to a node data type. This node data type gets its key_value
// as the key (argument) and child nodes as NULL.
// For all calls other than the first time, it further calls insertKey(int, node*).
void binaryTree::insertKey(int key)
{
if (root != NULL)
{
insertKey(key, root);
}
else
{
root = new node;
root->key_value = key;
root->left = NULL;
root->right = NULL;
}
}

// Inserts the key, such that the tree follows the definition of a binary tree.
// The function travels down the tree starting from the root to find a suitable position.
// If the key is less than the key_value at a node, the function calls itself with its left subtree.
// If the key is greater than or equal to the key_value at a node, the function calls itself with its right subtree.
// When it reaches a suitable place, it creates a new node. This node gets key_value as the key and child nodes as NULL.
void binaryTree::insertKey(int key, node *leaf)
{
if (key < leaf->key_value)
{
if (leaf->left != NULL)
{
insertKey(key, leaf->left);
}
else
{
leaf->left = new node;
leaf->left->key_value = key;
leaf->left->left = NULL;
leaf->left->right = NULL;
}
}
else if (key >= leaf->key_value)
{
if (leaf->right != NULL)
{
insertKey(key, leaf->right);
}
else
{
leaf->right = new node;
leaf->right->key_value = key;
leaf->right->left = NULL;
leaf->right->right = NULL;
}
}
}

// Recursive Post-Order Traversal
void binaryTree::postOrderTraversal_recursive()
{
cout << "PostOrderTraversal (recursive): ";
postOrderTraversal_recursive(root);
cout << endl;
}

void binaryTree::postOrderTraversal_recursive(node *leaf)
{
if (leaf != NULL)
{
postOrderTraversal_recursive(leaf->left);
postOrderTraversal_recursive(leaf->right);
cout << leaf->key_value << " ";
}
}

// Iterative Post-Order Traversal
void binaryTree::postOrderTraversal_iterative()
{
cout << "PostOrderTraversal (iterative): ";
if (root == NULL)
return;

stack<node *> nodeAddr;
node *currentNode = root;
node *lastNodeVisited = NULL;

while (!nodeAddr.empty() || currentNode != NULL)
{
if (currentNode != NULL)
{
nodeAddr.push(currentNode);
currentNode = currentNode->left;
}
else
{
node *topNode = nodeAddr.top();

if (topNode->right != NULL && lastNodeVisited != topNode->right)
{
currentNode = topNode->right;
}
else
{
cout << topNode->key_value << " ";
lastNodeVisited = topNode;
nodeAddr.pop();
}
}
}
}

int main()
{
binaryTree Tree;
vector<int> elements = {25, 15, 50, 10, 22, 35, 70, 4, 12, 18, 24, 31, 44, 66, 80}; // The elements to be inserted in the tree
Tree.insertKeys(elements);

Tree.postOrderTraversal_recursive(); // Expected: 4 12 10 18 24 22 15 31 44 35 66 80 70 50 25
Tree.postOrderTraversal_iterative(); // Expected: 4 12 10 18 24 22 15 31 44 35 66 80 70 50 25

cout << endl;
}

0 comments on commit c827c50

Please sign in to comment.