Skip to content

Commit 3633e13

Browse files
authored
Create README.md
1 parent bd9206a commit 3633e13

File tree

1 file changed

+295
-0
lines changed
  • 17 - Binary Tree Data Structure Problems/16 - Vertical Tree Traversal

1 file changed

+295
-0
lines changed
Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
<h1 align='center'>Vertical - Tree - Traversal</h1>
2+
3+
## Problem Statement
4+
5+
**Problem URL :** [Vertical Tree Traversal](https://www.geeksforgeeks.org/problems/print-a-binary-tree-in-vertical-order/1)
6+
7+
![image](https://github.com/user-attachments/assets/61935ab0-184f-4ce2-baee-d0764d92f9c0)
8+
![image](https://github.com/user-attachments/assets/59fda5a8-255f-476a-92c5-5b60c7875150)
9+
![image](https://github.com/user-attachments/assets/b8d34a2b-acf8-4e77-b8c9-fcc98233457f)
10+
11+
12+
## Problem Explanation
13+
14+
The objective of vertical tree traversal is to print the nodes of a binary tree in vertical order. In this traversal:
15+
- Nodes are printed vertically, from top to bottom.
16+
- Nodes that are on the same vertical line are printed together.
17+
- The vertical lines are defined based on the horizontal distance from the root node.
18+
19+
### Vertical Line Definition
20+
- Assign a horizontal distance (HD) to each node:
21+
- The HD of the root node is `0`.
22+
- For the left child, HD is `HD of parent - 1`.
23+
- For the right child, HD is `HD of parent + 1`.
24+
25+
### Example
26+
Consider the following binary tree:
27+
28+
```
29+
1
30+
/ \
31+
2 3
32+
/ \ \
33+
4 5 6
34+
/
35+
7
36+
```
37+
38+
**Vertical Order Output**:
39+
- Vertical lines:
40+
- HD -2: `4`
41+
- HD -1: `2`
42+
- HD 0: `1, 5, 7`
43+
- HD 1: `3`
44+
- HD 2: `6`
45+
46+
So the output will be:
47+
```
48+
4
49+
2
50+
1
51+
5
52+
7
53+
3
54+
6
55+
```
56+
57+
## Step 2: Approach
58+
59+
### Approach Explanation
60+
1. **Mapping HD**: Use a data structure (like a map) to map each HD to a list of nodes that fall under that HD.
61+
2. **Traversal**: Perform a level-order traversal (BFS or DFS) of the tree, updating the HD for each node:
62+
- For each node, add its value to the list corresponding to its HD in the map.
63+
- Recursively traverse the left child with `HD - 1` and the right child with `HD + 1`.
64+
3. **Output**: After collecting nodes in the map, output them in order of HD, from the smallest to the largest.
65+
66+
### Beginner-Friendly Steps
67+
1. Initialize a map to store nodes against their HDs.
68+
2. Start from the root node, initializing its HD to `0`.
69+
3. For each node, add its value to the corresponding list in the map.
70+
4. Traverse left and right children, adjusting the HD accordingly.
71+
5. Finally, iterate through the sorted keys of the map to print the node values.
72+
73+
## Problem Solution
74+
```cpp
75+
#include <map>
76+
#include <vector>
77+
#include <queue>
78+
using namespace std;
79+
80+
struct Node {
81+
int data;
82+
Node *left, *right;
83+
};
84+
85+
class Solution {
86+
public:
87+
void verticalOrder(Node* root) {
88+
if (root == NULL) return;
89+
90+
// Map to store nodes in vertical order
91+
map<int, vector<int>> verticalMap;
92+
93+
// Queue for BFS traversal with horizontal distance
94+
queue<pair<Node*, int>> q;
95+
q.push({root, 0}); // {node, horizontal distance}
96+
97+
while (!q.empty()) {
98+
auto [node, hd] = q.front(); // Get the front element
99+
q.pop();
100+
101+
// Store node data in the map according to horizontal distance
102+
verticalMap[hd].push_back(node->data);
103+
104+
// Push left child with HD - 1
105+
if (node->left) q.push({node->left, hd - 1});
106+
// Push right child with HD + 1
107+
if (node->right) q.push({node->right, hd + 1});
108+
}
109+
110+
// Output the vertical order
111+
for (const auto& pair : verticalMap) {
112+
for (int value : pair.second) {
113+
cout << value << " ";
114+
}
115+
cout << endl; // Newline for different verticals
116+
}
117+
}
118+
};
119+
```
120+
121+
## Problem Solution Explanation
122+
123+
1. **Include Libraries**
124+
```cpp
125+
#include <map>
126+
#include <vector>
127+
#include <queue>
128+
```
129+
- These lines include the necessary libraries:
130+
- `<map>`: For using the map data structure to store vertical nodes.
131+
- `<vector>`: For storing multiple values (nodes) corresponding to each vertical.
132+
- `<queue>`: For implementing the BFS (Breadth-First Search) traversal.
133+
134+
2. **Node Structure Definition**
135+
```cpp
136+
struct Node {
137+
int data;
138+
Node *left, *right;
139+
};
140+
```
141+
- This defines a `Node` structure to represent a binary tree node:
142+
- `data`: An integer storing the value of the node.
143+
- `left`: A pointer to the left child node.
144+
- `right`: A pointer to the right child node.
145+
146+
3. **Class Definition**
147+
```cpp
148+
class Solution {
149+
public:
150+
```
151+
- Defines the `Solution` class, which contains methods to solve the problem. The `public` access specifier indicates that the members of this class can be accessed from outside the class.
152+
153+
4. **Vertical Order Method Declaration**
154+
```cpp
155+
void verticalOrder(Node* root) {
156+
```
157+
- Declares the `verticalOrder` method that takes a pointer to the root of the binary tree as an argument.
158+
159+
5. **Check for Empty Tree**
160+
```cpp
161+
if (root == NULL) return;
162+
```
163+
- This line checks if the root node is `NULL`. If it is, the function immediately returns, as there are no nodes to process.
164+
165+
6. **Map Initialization**
166+
```cpp
167+
map<int, vector<int>> verticalMap;
168+
```
169+
- Initializes a map called `verticalMap` where:
170+
- The key is an integer (the horizontal distance from the root).
171+
- The value is a vector of integers (the node values at that horizontal distance).
172+
173+
7. **Queue Initialization for BFS**
174+
```cpp
175+
queue<pair<Node*, int>> q;
176+
q.push({root, 0}); // {node, horizontal distance}
177+
```
178+
- Declares a queue named `q` to facilitate level-order traversal. Each element in the queue is a pair consisting of:
179+
- A pointer to the node (`Node*`).
180+
- An integer representing the horizontal distance (HD) of that node.
181+
- Pushes the root node into the queue with an HD of `0`.
182+
183+
8. **BFS Loop**
184+
```cpp
185+
while (!q.empty()) {
186+
```
187+
- Starts a loop that continues as long as the queue is not empty, indicating there are still nodes to process.
188+
189+
9. **Extract Node and HD**
190+
```cpp
191+
auto [node, hd] = q.front(); // Get the front element
192+
q.pop();
193+
```
194+
- Uses structured bindings (C++17 feature) to unpack the front element of the queue into `node` and `hd`.
195+
- `q.front()` retrieves the element at the front of the queue without removing it.
196+
- `q.pop()` removes the front element from the queue after retrieving it.
197+
198+
10. **Store Node Data in Map**
199+
```cpp
200+
verticalMap[hd].push_back(node->data);
201+
```
202+
- This line adds the current node's data to the vector in `verticalMap` that corresponds to its horizontal distance (`hd`).
203+
204+
11. **Push Left Child into Queue**
205+
```cpp
206+
if (node->left) q.push({node->left, hd - 1});
207+
```
208+
- If the current node has a left child, it is pushed into the queue with an HD of `hd - 1` (since left children are one unit closer to the left).
209+
210+
12. **Push Right Child into Queue**
211+
```cpp
212+
if (node->right) q.push({node->right, hd + 1});
213+
```
214+
- If the current node has a right child, it is pushed into the queue with an HD of `hd + 1` (since right children are one unit closer to the right).
215+
216+
13. **Output Vertical Order**
217+
```cpp
218+
for (const auto& pair : verticalMap) {
219+
```
220+
- This loop iterates through each key-value pair in the `verticalMap`.
221+
222+
14. **Print Node Values for Each Vertical**
223+
```cpp
224+
for (int value : pair.second) {
225+
cout << value << " ";
226+
}
227+
cout << endl; // Newline for different verticals
228+
```
229+
- The inner loop iterates through the vector of node values (`pair.second`) corresponding to each HD and prints each value followed by a space.
230+
- After printing all values for a vertical line, it outputs a newline for better readability.
231+
232+
233+
## Step 4: Output Examples with Explanation
234+
235+
### Example 1
236+
Given the tree:
237+
```
238+
1
239+
/ \
240+
2 3
241+
/ \ \
242+
4 5 6
243+
/
244+
7
245+
```
246+
247+
**Output**:
248+
```
249+
4
250+
2
251+
1 5 7
252+
3
253+
6
254+
```
255+
256+
### Explanation
257+
- The first vertical (HD -2) contains node `4`.
258+
- The second vertical (HD -1) contains node `2`.
259+
- The third vertical (HD 0) contains nodes `1`, `5`, and `7` printed together.
260+
- The fourth vertical (HD 1) contains node `3`.
261+
- The fifth vertical (HD 2) contains node `6`.
262+
263+
### Example 2
264+
For a single node tree:
265+
```
266+
1
267+
```
268+
269+
**Output**:
270+
```
271+
1
272+
```
273+
274+
### Explanation
275+
- The tree consists only of the root node, which is also the only node at HD `0`.
276+
277+
## Step 5: Time and Space Complexity
278+
279+
### Time Complexity
280+
- The algorithm performs a level-order traversal (BFS) of the binary tree:
281+
- Each node is visited once.
282+
- Therefore, the time complexity is **O(n)**, where `n` is the number of nodes in the tree.
283+
284+
### Space Complexity
285+
- The space complexity is determined by:
286+
- The queue used for BFS: In the worst case (a balanced tree), it can hold up to `O(w)` nodes, where `w` is the maximum width of the tree.
287+
- The map that stores vertical values: In the worst case, it can also hold `O(n)` nodes if every node is in a different vertical.
288+
289+
Thus, the space complexity is **O(n)** in the worst case due to storing nodes in the map.
290+
291+
### Summary
292+
- **Time Complexity**: **O(n)**
293+
- **Space Complexity**: **O(n)**
294+
295+
This thorough explanation covers the vertical tree traversal problem from understanding the problem statement to implementation and analysis of the code. If you have any questions or need further clarification, feel free to ask!

0 commit comments

Comments
 (0)