Print Tree Perimeter
Given a binary tree, print its perimeter nodes.
Statement
Given the root node of a binary tree, print the nodes that form its perimeter (boundary). We must print the perimeter of the binary tree in three phases (order is important):
- Left boundary
- Leaf nodes
- Right boundary
Example
In the following tree, the nodes highlighted in green, form the perimeter.
The expected output for the tree above is: 100, 50, 25, 10, 70, 400, 350, 200.
Sample input
The input list below represents the level-order traversal of the binary tree:
[100, 50, 200, 25, 60, 350, 10, 70, 400]
Expected output
The sequence below represents the perimeter of the binary tree:
100, 50, 25, 10, 70, 400, 350, 200
Try it yourself
Note: The binary tree node’s class has members
left
andright
to store references to other nodes, along with the memberdata
to hold the node’s value.
#include "BinaryTree.cpp"#include <stack>#include <string>using namespace std;void DisplayTreePerimeter(BinaryTreeNode* root) {// TODO: Write - Your - Codecout << "";}
Solution 1
We print the perimeter of the binary tree in three phases, the left boundary, leaf nodes, and the right boundary. The left and right boundaries will be printed iteratively while the leaf nodes will be printed recursively. Here is how the algorithm looks:
- Print the root node.
- Print the left boundary in top-down order.
- Print the leaf nodes in left-right order. We’ll be traversing from one leaf node to the next using post-order traversal.
- Print the right boundary in bottom-up order.
- We push the node values in a stack here.
- Once we hit the leaf node, we pop all stack elements while printing them.
#include "BinaryTree.cpp"#include <string>#include <stack>using namespace std;// Function to print left tree perimetervoid PrintLeftPerimeter(BinaryTreeNode* root, string& result) {while (root != nullptr) {int curr_val = root->data;// Setting root such that left boundary nodes are printed from top to bottomif (root->left != nullptr) {root = root->left;} else if (root->right != nullptr) {root = root->right;} else {// Break loop on leaf nodebreak;}// Append current node to perimeter resultresult += to_string(curr_val) + ", ";}}// Function to print right tree perimetervoid PrintRightPerimeter(BinaryTreeNode* root, string& result) {// Stack for right side values.stack<int> r_values;while (root != nullptr) {int curr_val = root->data;// Setting root such that right boundary nodes are stored in stack of// right-side values from top to bottomif (root->right != nullptr) {root = root->right;} else if (root->left != nullptr) {root = root->left;} else {// Break loop on leaf nodebreak;}r_values.push(curr_val);}// Appending nodes in reverse order to perimeter resultwhile (r_values.empty() == false) {result += to_string(r_values.top()) + ", ";r_values.pop();}}// Function to print leaf nodes perimetervoid PrintLeafNodes(BinaryTreeNode* root, string& result) {// Recursively traversing to leaf nodesif (root != nullptr) {PrintLeafNodes(root->left, result);PrintLeafNodes(root->right, result);// Append node to result if it's a leaf nodeif (root->left == nullptr && root->right == nullptr) {result += to_string(root->data) + ", ";}}}void DisplayTreePerimeter(BinaryTreeNode* root) {string result = "";if (root != nullptr) {// If the tree is not null , we immediately add root to our perimeter resultresult += to_string(root->data) + ", ";// Calling function to print left boundary nodePrintLeftPerimeter(root->left, result);// Calling function to print leaf nodesif (root->left != nullptr || root->right != nullptr) {// We don't need to print if root is also the leaf node.PrintLeafNodes(root, result);}// Calling function to print right boundary nodePrintRightPerimeter(root->right, result);// Removing trailing comma and space from our resultif (result.length() > 2) {result = result.substr(0, result.length() - 2);}cout << result;}}int main() {// Creating a binary treevector<int> input1 = {100, 50, 200, 25, 75, 125, 350, 250, 750, 12, 35, 60, 80, 110, 150};BinaryTree *tree1 = new BinaryTree(input1);// Creating a binary tree with wrong node in left subtreeBinaryTree *tree2 = new BinaryTree(100);tree2->Insert(50);tree2->Insert(200);tree2->Insert(25);// Add a node at an incorrect positiontree2->InsertBT(110);tree2->Insert(125);tree2->Insert(350);tree2->Insert(250);tree2->Insert(750);tree2->Insert(12);tree2->Insert(35);tree2->InsertBT(60);tree2->InsertBT(80);tree2->InsertBT(120);// Creating a binary tree with wrong node in right subtreeBinaryTree *tree3 = new BinaryTree(100);tree3->Insert(50);tree3->Insert(200);tree3->Insert(25);tree3->Insert(75);// Add a node at an incorrect positiontree3->InsertBT(90);tree3->Insert(350);tree3->Insert(250);tree3->Insert(750);tree3->Insert(12);tree3->Insert(35);tree3->InsertBT(60);tree3->InsertBT(80);tree3->InsertBT(110);// Creating a right degenerate binary treevector<int> input4 = {25, 50, 75, 100, 125, 200, 350};BinaryTree *tree4 = new BinaryTree(input4);// Creating a left degenerate binary treevector<int> input5 = {350, 200, 125, 100, 75, 50, 25};BinaryTree *tree5 = new BinaryTree(input5);// Creating a single node binary treeBinaryTree *tree6 = new BinaryTree(100);// Defining Test Casesvector<BinaryTreeNode*> test_cases_roots = {tree1->root, tree2->root, tree3->root, tree4->root, tree5->root, tree6->root, nullptr};for (int i = 0; i < test_cases_roots.size(); i++) {if (i > 0) {cout << endl;}cout << i + 1 << ".\tBinary tree" << endl;DisplayTree(test_cases_roots[i]);cout << "\n\tTree Perimeter:\n\t";DisplayTreePerimeter(test_cases_roots[i]);cout << "\n----------------------------------------------------------------------------------------------------\n";}}
Time complexity
The Time complexity of ...