#include <iostream>
#include <functional>
#include <stack>
struct tNode {
char data;
struct tNode *left;
struct tNode *right;
};
// Function to create a new node
tNode *newNode(char data) {
tNode *node = new tNode;
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}
// Function to insert nodes in level order
tNode *insertLevelOrder(char arr[], tNode *root, int i, int n) {
// Base case for recursion
if (i < n) {
tNode *temp = newNode(arr[i]);
root = temp;
// insert left child
root->left = insertLevelOrder(arr, root->left, 2 * i + 1, n);
// insert right child
root->right = insertLevelOrder(arr, root->right, 2 * i + 2, n);
}
return root;
}
// Function to delete the given tree
void deleteTree(tNode *node) {
if (node == NULL)
return;
/* first delete both subtrees */
deleteTree(node->left);
deleteTree(node->right);
/* then delete the node */
// std::cout << "Deleting node: " << node->data << std::endl;
delete node;
}
void in_order(tNode* node, const std::function<void(tNode*)>& visitor) {
if (node == nullptr) {
return;
};
in_order(node->left, visitor);
visitor(node);
in_order(node->right, visitor);
}
void pre_order_stack(tNode* root, const std::function<void(tNode*)>& visitor) {
std::stack<tNode*> stack;
stack.push(root);
while (!stack.empty()) {
tNode *curr = stack.top();
stack.pop();
visitor(curr);
// With this approach we visit "null" nodes, which can be useful.
// Alternatively we could move the condition to the push:
//if (curr->right != nullptr) stack.push(curr->right);
if (curr == nullptr) continue;
if (curr->right!=NULL) {
stack.push(curr->right);
}
if (curr->left!=NULL) {
stack.push(curr->left);
}
}
}
void post_order_nonrecursive(tNode *root, const std::function<void(tNode*)>& visitor) {
std::stack<tNode*> s;
tNode *current = root;
while (true) {
// Explore left, but remember node & right child
if (current != nullptr) {
if (current->right != nullptr)
s.push(current->right);
s.push(current);
current = current->left;
continue;
}
// current == nullptr
if (s.empty()) return;
current = s.top();
s.pop();
// If we have the right child remembered,
// it would be on the top of the stack.
if (current->right && !s.empty() && current->right == s.top()) {
// if it is, we must visit it (and it's children) first
s.pop();
s.push(current);
current = current->right;
} else {
visitor(current);
current = nullptr;
}
}
}
// Driver program to test above function
int main() {
char arr[]={'+','2','+',NULL,NULL,'2','*',NULL,NULL,NULL,NULL,NULL,NULL,'2','+',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2','2'};
tNode *root = insertLevelOrder(arr, root, 0, 31);
in_order(root, [](tNode* node){std::cout << node->data << " ";});
std::cout<<"\n";
pre_order_stack(root, [](tNode* node){std::cout << node->data << " ";});
std::cout<<"\n";
post_order_nonrecursive(root, [](tNode* node){std::cout << node->data << " ";});
deleteTree(root);
root = NULL;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPHN0YWNrPgoKc3RydWN0IHROb2RlIHsKICBjaGFyIGRhdGE7CiAgc3RydWN0IHROb2RlICpsZWZ0OwogIHN0cnVjdCB0Tm9kZSAqcmlnaHQ7Cn07CgovLyBGdW5jdGlvbiB0byBjcmVhdGUgYSBuZXcgbm9kZQp0Tm9kZSAqbmV3Tm9kZShjaGFyIGRhdGEpIHsKICB0Tm9kZSAqbm9kZSA9IG5ldyB0Tm9kZTsKICBub2RlLT5kYXRhID0gZGF0YTsKICBub2RlLT5sZWZ0ID0gTlVMTDsKICBub2RlLT5yaWdodCA9IE5VTEw7CiAgcmV0dXJuIG5vZGU7Cn0KCi8vIEZ1bmN0aW9uIHRvIGluc2VydCBub2RlcyBpbiBsZXZlbCBvcmRlcgp0Tm9kZSAqaW5zZXJ0TGV2ZWxPcmRlcihjaGFyIGFycltdLCB0Tm9kZSAqcm9vdCwgaW50IGksIGludCBuKSB7CiAgLy8gQmFzZSBjYXNlIGZvciByZWN1cnNpb24KICBpZiAoaSA8IG4pIHsKICAgIHROb2RlICp0ZW1wID0gbmV3Tm9kZShhcnJbaV0pOwogICAgcm9vdCA9IHRlbXA7CgogICAgLy8gaW5zZXJ0IGxlZnQgY2hpbGQKICAgIHJvb3QtPmxlZnQgPSBpbnNlcnRMZXZlbE9yZGVyKGFyciwgcm9vdC0+bGVmdCwgMiAqIGkgKyAxLCBuKTsKCiAgICAvLyBpbnNlcnQgcmlnaHQgY2hpbGQKICAgIHJvb3QtPnJpZ2h0ID0gaW5zZXJ0TGV2ZWxPcmRlcihhcnIsIHJvb3QtPnJpZ2h0LCAyICogaSArIDIsIG4pOwogIH0KICByZXR1cm4gcm9vdDsKfQoKLy8gRnVuY3Rpb24gdG8gZGVsZXRlIHRoZSBnaXZlbiB0cmVlCnZvaWQgZGVsZXRlVHJlZSh0Tm9kZSAqbm9kZSkgewogIGlmIChub2RlID09IE5VTEwpCiAgICByZXR1cm47CgogIC8qIGZpcnN0IGRlbGV0ZSBib3RoIHN1YnRyZWVzICovCiAgZGVsZXRlVHJlZShub2RlLT5sZWZ0KTsKICBkZWxldGVUcmVlKG5vZGUtPnJpZ2h0KTsKCiAgLyogdGhlbiBkZWxldGUgdGhlIG5vZGUgKi8KICAvLyBzdGQ6OmNvdXQgPDwgIkRlbGV0aW5nIG5vZGU6ICIgPDwgbm9kZS0+ZGF0YSA8PCBzdGQ6OmVuZGw7CiAgZGVsZXRlIG5vZGU7Cn0Kdm9pZCBpbl9vcmRlcih0Tm9kZSogbm9kZSwgY29uc3Qgc3RkOjpmdW5jdGlvbjx2b2lkKHROb2RlKik+JiB2aXNpdG9yKSB7CiAgICBpZiAobm9kZSA9PSBudWxscHRyKSB7CiAgICAJcmV0dXJuOwogICAgfTsKICAgIGluX29yZGVyKG5vZGUtPmxlZnQsIHZpc2l0b3IpOwogICAgdmlzaXRvcihub2RlKTsKICAgIGluX29yZGVyKG5vZGUtPnJpZ2h0LCB2aXNpdG9yKTsKfQp2b2lkIHByZV9vcmRlcl9zdGFjayh0Tm9kZSogcm9vdCwgY29uc3Qgc3RkOjpmdW5jdGlvbjx2b2lkKHROb2RlKik+JiB2aXNpdG9yKSB7CiAgICBzdGQ6OnN0YWNrPHROb2RlKj4gc3RhY2s7CiAgICBzdGFjay5wdXNoKHJvb3QpOwogICAgd2hpbGUgKCFzdGFjay5lbXB0eSgpKSB7CiAgICAgICAgdE5vZGUgKmN1cnIgPSBzdGFjay50b3AoKTsKICAgICAgICBzdGFjay5wb3AoKTsKICAgICAgICB2aXNpdG9yKGN1cnIpOwogICAgICAgIC8vIFdpdGggdGhpcyBhcHByb2FjaCB3ZSB2aXNpdCAibnVsbCIgbm9kZXMsIHdoaWNoIGNhbiBiZSB1c2VmdWwuCiAgICAgICAgLy8gQWx0ZXJuYXRpdmVseSB3ZSBjb3VsZCBtb3ZlIHRoZSBjb25kaXRpb24gdG8gdGhlIHB1c2g6CiAgICAgICAgLy9pZiAoY3Vyci0+cmlnaHQgIT0gbnVsbHB0cikgc3RhY2sucHVzaChjdXJyLT5yaWdodCk7CiAgICAgICAgaWYgKGN1cnIgPT0gbnVsbHB0cikgY29udGludWU7CgogICAgICAgIGlmIChjdXJyLT5yaWdodCE9TlVMTCkgewogICAgICAgICAgICBzdGFjay5wdXNoKGN1cnItPnJpZ2h0KTsKICAgICAgICB9CiAgICAgICAgaWYgKGN1cnItPmxlZnQhPU5VTEwpIHsKICAgICAgICAgICAgc3RhY2sucHVzaChjdXJyLT5sZWZ0KTsKICAgICAgICB9CgogICAgfQp9CnZvaWQgcG9zdF9vcmRlcl9ub25yZWN1cnNpdmUodE5vZGUgKnJvb3QsIGNvbnN0IHN0ZDo6ZnVuY3Rpb248dm9pZCh0Tm9kZSopPiYgdmlzaXRvcikgewogICAgc3RkOjpzdGFjazx0Tm9kZSo+IHM7CiAgICB0Tm9kZSAqY3VycmVudCA9IHJvb3Q7CiAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgIC8vIEV4cGxvcmUgbGVmdCwgYnV0IHJlbWVtYmVyIG5vZGUgJiByaWdodCBjaGlsZAogICAgICAgIGlmIChjdXJyZW50ICE9IG51bGxwdHIpIHsKICAgICAgICAgICAgaWYgKGN1cnJlbnQtPnJpZ2h0ICE9IG51bGxwdHIpCiAgICAgICAgICAgICAgICBzLnB1c2goY3VycmVudC0+cmlnaHQpOwogICAgICAgICAgICBzLnB1c2goY3VycmVudCk7CiAgICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50LT5sZWZ0OwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgLy8gY3VycmVudCA9PSBudWxscHRyCiAgICAgICAgaWYgKHMuZW1wdHkoKSkgcmV0dXJuOwogICAgICAgIGN1cnJlbnQgPSBzLnRvcCgpOwogICAgICAgIHMucG9wKCk7CiAgICAgICAgLy8gSWYgd2UgaGF2ZSB0aGUgcmlnaHQgY2hpbGQgcmVtZW1iZXJlZCwgCiAgICAgICAgLy8gaXQgd291bGQgYmUgb24gdGhlIHRvcCBvZiB0aGUgc3RhY2suCiAgICAgICAgaWYgKGN1cnJlbnQtPnJpZ2h0ICYmICFzLmVtcHR5KCkgJiYgY3VycmVudC0+cmlnaHQgPT0gcy50b3AoKSkgewogICAgICAgICAgICAvLyBpZiBpdCBpcywgd2UgbXVzdCB2aXNpdCBpdCAoYW5kIGl0J3MgY2hpbGRyZW4pIGZpcnN0CiAgICAgICAgICAgIHMucG9wKCk7CiAgICAgICAgICAgIHMucHVzaChjdXJyZW50KTsKICAgICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQtPnJpZ2h0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZpc2l0b3IoY3VycmVudCk7CiAgICAgICAgICAgIGN1cnJlbnQgPSBudWxscHRyOwogICAgICAgIH0KICAgIH0KfQovLyBEcml2ZXIgcHJvZ3JhbSB0byB0ZXN0IGFib3ZlIGZ1bmN0aW9uCmludCBtYWluKCkgewogIGNoYXIgYXJyW109eycrJywnMicsJysnLE5VTEwsTlVMTCwnMicsJyonLE5VTEwsTlVMTCxOVUxMLE5VTEwsTlVMTCxOVUxMLCcyJywnKycsTlVMTCxOVUxMLE5VTEwsTlVMTCxOVUxMLE5VTEwsTlVMTCxOVUxMLE5VTEwsTlVMTCxOVUxMLE5VTEwsTlVMTCxOVUxMLCcyJywnMid9OwogIHROb2RlICpyb290ID0gaW5zZXJ0TGV2ZWxPcmRlcihhcnIsIHJvb3QsIDAsIDMxKTsKICBpbl9vcmRlcihyb290LCBbXSh0Tm9kZSogbm9kZSl7c3RkOjpjb3V0IDw8IG5vZGUtPmRhdGEgPDwgIiAiO30pOwogIHN0ZDo6Y291dDw8IlxuIjsKICBwcmVfb3JkZXJfc3RhY2socm9vdCwgW10odE5vZGUqIG5vZGUpe3N0ZDo6Y291dCA8PCBub2RlLT5kYXRhIDw8ICIgIjt9KTsKICBzdGQ6OmNvdXQ8PCJcbiI7CiAgcG9zdF9vcmRlcl9ub25yZWN1cnNpdmUocm9vdCwgW10odE5vZGUqIG5vZGUpe3N0ZDo6Y291dCA8PCBub2RlLT5kYXRhIDw8ICIgIjt9KTsKICBkZWxldGVUcmVlKHJvb3QpOwogIHJvb3QgPSBOVUxMOwoKICByZXR1cm4gMDsKfQ==