Skip to content

Commit 593480f

Browse files
authored
Merge pull request #1330 from akgmage/dev
Dev
2 parents 912694e + 709a1bc commit 593480f

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

Trees/Binary Trees/is_symmetric.cpp

+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
Write a function that takes in a Binary Tree and returns if that tree is symmetrical. A tree is symmetrical
3+
if the left and right subtrees are mirror images of each other.
4+
5+
Explanation:
6+
7+
1. The code defines a class `BinaryTree` representing a binary tree node. It has an `int` value and pointers
8+
to its left and right children.
9+
2. The `SymmetricalTree` function is the main entry point. It calls the helper function `treesAreMirrored`
10+
to check if the left and right subtrees are mirrored.
11+
3. The `treesAreMirrored` function checks if two binary trees are mirrored. It uses recursion to compare
12+
corresponding nodes in the left and right subtrees.
13+
4. In the `treesAreMirrored` function, the base case checks if both the left and right trees are non-null
14+
and have the same value. If so, it recursively checks if their subtrees are mirrored.
15+
5. If either the left or right tree is null or their values are not equal, they are not mirrored.
16+
If both the left and right trees are null, they are considered mirrored.
17+
6. In the `main` function, a binary tree is created for testing purposes.
18+
7. The `SymmetricalTree` function is called to check if the binary tree is symmetrical.
19+
8. The result is printed to the console.
20+
9. Memory cleanup is performed by deleting the dynamically allocated nodes.
21+
22+
The time and space complexity of the given code snippet can be analyzed as follows:
23+
24+
1. Time Complexity:
25+
- The `SymmetricalTree` function calls the `treesAreMirrored` function, which performs a recursive traversal of the binary tree.
26+
- In the worst case, the recursion visits each node once, so the time complexity is O(N), where N is the number of nodes in the tree.
27+
28+
2. Space Complexity:
29+
- The space complexity is determined by the maximum depth of the recursion stack.
30+
- In the worst case, the binary tree is linear, resulting in a recursion depth of N, where N is the number of nodes in the tree.
31+
- Therefore, the space complexity is O(N) due to the recursion stack usage.
32+
33+
It's important to note that the space complexity can be optimized by using an iterative approach instead of recursion. By using an iterative algorithm that leverages a stack or queue to perform a level-order traversal, we can achieve a space complexity of O(W), where W is the maximum width (number of nodes at the same level) of the binary tree.
34+
35+
*/
36+
#include <iostream>
37+
38+
using namespace std;
39+
40+
// This is an input class. Do not edit.
41+
class BinaryTree {
42+
public:
43+
int Value;
44+
BinaryTree* Left;
45+
BinaryTree* Right;
46+
};
47+
48+
// SymmetricalTree checks if a binary tree is symmetrical.
49+
bool SymmetricalTreeRecursive(BinaryTree* tree) {
50+
// Call the helper function to check if the left and right subtrees are mirrored.
51+
return treesAreMirrored(tree->Left, tree->Right);
52+
}
53+
54+
// treesAreMirrored checks if two binary trees are mirrored.
55+
bool treesAreMirrored(BinaryTree* left, BinaryTree* right) {
56+
// Base case: If both left and right trees are non-null and have the same value,
57+
// recursively check if their subtrees are mirrored.
58+
if (left != nullptr && right != nullptr && left->Value == right->Value) {
59+
return treesAreMirrored(left->Left, right->Right) && treesAreMirrored(left->Right, right->Left);
60+
}
61+
62+
// If either left or right tree is null or their values are not equal, they are not mirrored.
63+
// Also, if both left and right trees are null, they are considered mirrored.
64+
return left == right;
65+
}
66+
67+
// Approach 2: Iterative Approach using Stack
68+
/*
69+
In this iterative approach, we use two stacks (stackLeft and stackRight) to perform a mirror traversal of the
70+
left and right subtrees. The process is similar to the original code snippet but implemented iteratively
71+
using a while loop and stacks. The stacks are initialized with the left and right children of the root node,
72+
and in each iteration, we compare the corresponding nodes from both stacks and check for asymmetry.
73+
The children of the left and right nodes are pushed onto their respective stacks in reverse order to
74+
maintain the mirror traversal. The loop continues until both stacks are empty or an asymmetry is detected.
75+
Finally, the function returns whether the tree is symmetric or not.
76+
77+
The time complexity of this algorithm is O(n), where n is the number of nodes in the binary tree, as
78+
it traverses each node once. The space complexity is O(max(d, h)), where d is the maximum width of
79+
the tree (number of nodes at the widest level) and h is the height of the tree. The space complexity
80+
depends on the maximum number of nodes stored in the stacks during the traversal.
81+
82+
83+
*/
84+
struct BinaryTree {
85+
int value;
86+
BinaryTree* left;
87+
BinaryTree* right;
88+
};
89+
90+
bool SymmetricalTreeIterative(BinaryTree* tree) {
91+
std::stack<BinaryTree*> stackLeft;
92+
std::stack<BinaryTree*> stackRight;
93+
stackLeft.push(tree->left); // Initialize stackLeft with the left child of the root node
94+
stackRight.push(tree->right); // Initialize stackRight with the right child of the root node
95+
96+
// Perform mirror traversal of the left and right subtrees
97+
while (!stackLeft.empty()) {
98+
BinaryTree* left = stackLeft.top();
99+
BinaryTree* right = stackRight.top();
100+
stackLeft.pop();
101+
stackRight.pop();
102+
103+
if (left == nullptr && right == nullptr) {
104+
continue; // Both left and right subtrees are symmetric, continue to the next iteration
105+
}
106+
107+
if (left == nullptr || right == nullptr || left->value != right->value) {
108+
return false; // Asymmetry detected, tree is not symmetric
109+
}
110+
111+
// Push the children of left and right onto the respective stacks in reverse order
112+
stackLeft.push(left->left);
113+
stackLeft.push(left->right);
114+
stackRight.push(right->right);
115+
stackRight.push(right->left);
116+
}
117+
118+
return true; // Tree is symmetric
119+
}
120+
121+
122+
int main() {
123+
// Create a binary tree for testing
124+
BinaryTree* tree = new BinaryTree();
125+
tree->Value = 1;
126+
tree->Left = new BinaryTree();
127+
tree->Left->Value = 2;
128+
tree->Right = new BinaryTree();
129+
tree->Right->Value = 2;
130+
tree->Left->Left = new BinaryTree();
131+
tree->Left->Left->Value = 3;
132+
tree->Right->Right = new BinaryTree();
133+
tree->Right->Right->Value = 3;
134+
135+
// Check if the tree is symmetrical
136+
bool isSymmetrical = SymmetricalTree(tree);
137+
138+
// Output the result
139+
if (isSymmetrical) {
140+
cout << "The binary tree is symmetrical." << endl;
141+
} else {
142+
cout << "The binary tree is not symmetrical." << endl;
143+
}
144+
145+
// Clean up the allocated memory
146+
delete tree->Left->Left;
147+
delete tree->Right->Right;
148+
delete tree->Left;
149+
delete tree->Right;
150+
delete tree;
151+
152+
return 0;
153+
}

0 commit comments

Comments
 (0)