Skip to content

Commit 3af6f20

Browse files
authored
Update README.md
1 parent 3633e13 commit 3af6f20

File tree

1 file changed

+131
-150
lines changed
  • 17 - Binary Tree Data Structure Problems/16 - Vertical Tree Traversal

1 file changed

+131
-150
lines changed

17 - Binary Tree Data Structure Problems/16 - Vertical Tree Traversal/README.md

Lines changed: 131 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -72,224 +72,205 @@ So the output will be:
7272

7373
## Problem Solution
7474
```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
75+
class Solution
76+
{
77+
public:
78+
//Function to find the vertical order traversal of Binary Tree.
79+
vector<int> verticalOrder(Node *root)
80+
{
81+
map<int, map<int, vector<int> >> nodes;
82+
queue<pair<Node*, pair<int, int> >> q;
83+
84+
vector<int> ans;
85+
if(root == NULL) return ans;
86+
87+
q.push(make_pair(root, make_pair(0, 0)));
88+
89+
while(!q.empty()){
90+
pair<Node*, pair<int, int> > temp = q.front();
9991
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});
92+
Node* frontNode = temp.first;
93+
int hd = temp.second.first;
94+
int lvl = temp.second.second;
95+
96+
nodes[hd][lvl].push_back(frontNode -> data);
97+
98+
if(frontNode -> left)
99+
q.push(make_pair(frontNode -> left, make_pair(hd -1 , lvl + 1)));
100+
101+
if(frontNode -> right)
102+
q.push(make_pair(frontNode -> right, make_pair(hd + 1, lvl + 1)));
108103
}
109-
110-
// Output the vertical order
111-
for (const auto& pair : verticalMap) {
112-
for (int value : pair.second) {
113-
cout << value << " ";
104+
105+
for(auto i : nodes){
106+
for(auto j : i.second){
107+
for(auto k : j.second){
108+
ans.push_back(k);
109+
}
114110
}
115-
cout << endl; // Newline for different verticals
116111
}
112+
113+
114+
return ans;
117115
}
118116
};
119117
```
120118

121119
## Problem Solution Explanation
122120

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.
121+
Let's break down the provided source code for the vertical order traversal of a binary tree. This code uses a combination of a queue for level-order traversal and a nested map to store node values by their horizontal and vertical distances.
133122

134-
2. **Node Structure Definition**
123+
1. **Class Definition**
135124
```cpp
136-
struct Node {
137-
int data;
138-
Node *left, *right;
139-
};
125+
class Solution
126+
{
127+
public:
140128
```
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.
129+
- Defines the `Solution` class, which will contain the method for vertical order traversal.
145130
146-
3. **Class Definition**
131+
2. **Vertical Order Method Declaration**
147132
```cpp
148-
class Solution {
149-
public:
133+
vector<int> verticalOrder(Node *root)
134+
{
150135
```
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.
136+
- Declares the `verticalOrder` method, which takes a pointer to the root of the binary tree as its argument and returns a vector of integers.
152137

153-
4. **Vertical Order Method Declaration**
138+
3. **Nested Map Initialization**
154139
```cpp
155-
void verticalOrder(Node* root) {
140+
map<int, map<int, vector<int> >> nodes;
156141
```
157-
- Declares the `verticalOrder` method that takes a pointer to the root of the binary tree as an argument.
142+
- Initializes a nested map called `nodes`:
143+
- The outer map's key (`int`) represents the horizontal distance from the root.
144+
- The inner map's key (`int`) represents the level of the node, with the value being a vector of integers (the node data at that horizontal distance and level).
158145

159-
5. **Check for Empty Tree**
146+
4. **Queue Initialization for BFS**
160147
```cpp
161-
if (root == NULL) return;
148+
queue<pair<Node*, pair<int, int> >> q;
162149
```
163-
- This line checks if the root node is `NULL`. If it is, the function immediately returns, as there are no nodes to process.
150+
- Declares a queue `q` to perform level-order traversal, where each element is a pair consisting of:
151+
- A pointer to the node (`Node*`).
152+
- A pair of integers representing the horizontal distance and the level of the node.
164153

165-
6. **Map Initialization**
154+
5. **Output Vector Initialization**
166155
```cpp
167-
map<int, vector<int>> verticalMap;
156+
vector<int> ans;
157+
if(root == NULL) return ans;
168158
```
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).
159+
- Initializes a vector `ans` to store the final vertical order traversal result.
160+
- Checks if the root is `NULL`, returning an empty vector if it is, as there are no nodes to process.
172161

173-
7. **Queue Initialization for BFS**
162+
6. **Push Root into Queue**
174163
```cpp
175-
queue<pair<Node*, int>> q;
176-
q.push({root, 0}); // {node, horizontal distance}
164+
q.push(make_pair(root, make_pair(0, 0)));
177165
```
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`.
166+
- Pushes the root node into the queue with a horizontal distance (`hd`) of `0` and level (`lvl`) of `0`.
182167

183-
8. **BFS Loop**
168+
7. **BFS Loop**
184169
```cpp
185-
while (!q.empty()) {
170+
while(!q.empty()){
186171
```
187172
- Starts a loop that continues as long as the queue is not empty, indicating there are still nodes to process.
188173
189-
9. **Extract Node and HD**
174+
8. **Extract Node, HD, and Level**
190175
```cpp
191-
auto [node, hd] = q.front(); // Get the front element
176+
pair<Node*, pair<int, int> > temp = q.front();
192177
q.pop();
178+
Node* frontNode = temp.first;
179+
int hd = temp.second.first;
180+
int lvl = temp.second.second;
193181
```
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.
182+
- Retrieves the front element of the queue and unpacks it into `temp`, which contains:
183+
- `frontNode`: The current node being processed.
184+
- `hd`: The horizontal distance of `frontNode`.
185+
- `lvl`: The level of `frontNode`.
186+
- Calls `q.pop()` to remove the processed node from the queue.
197187

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`).
188+
9. **Store Node Data in Map**
189+
```cpp
190+
nodes[hd][lvl].push_back(frontNode -> data);
191+
```
192+
- Stores the current node's data in the nested map `nodes` based on its horizontal distance (`hd`) and level (`lvl`).
203193

204-
11. **Push Left Child into Queue**
194+
10. **Push Left Child into Queue**
205195
```cpp
206-
if (node->left) q.push({node->left, hd - 1});
196+
if(frontNode -> left)
197+
q.push(make_pair(frontNode -> left, make_pair(hd -1 , lvl + 1)));
207198
```
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).
199+
- If the current node has a left child, it is pushed into the queue with:
200+
- Horizontal distance (`hd - 1`) because the left child is one unit to the left.
201+
- Level (`lvl + 1`) because it is one level deeper.
209202

210-
12. **Push Right Child into Queue**
203+
11. **Push Right Child into Queue**
211204
```cpp
212-
if (node->right) q.push({node->right, hd + 1});
205+
if(frontNode -> right)
206+
q.push(make_pair(frontNode -> right, make_pair(hd + 1, lvl + 1)));
213207
```
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).
208+
- If the current node has a right child, it is pushed into the queue with:
209+
- Horizontal distance (`hd + 1`) because the right child is one unit to the right.
210+
- Level (`lvl + 1`) because it is one level deeper.
215211

216-
13. **Output Vertical Order**
212+
12. **Output the Vertical Order**
217213
```cpp
218-
for (const auto& pair : verticalMap) {
214+
for(auto i : nodes){
215+
for(auto j : i.second){
216+
for(auto k : j.second){
217+
ans.push_back(k);
218+
}
219+
}
220+
}
219221
```
220-
- This loop iterates through each key-value pair in the `verticalMap`.
222+
- This nested loop iterates through the `nodes` map:
223+
- The outer loop iterates through each horizontal distance (`i`).
224+
- The middle loop iterates through each level at that horizontal distance (`j`).
225+
- The inner loop iterates through each node value at that level and pushes it into the `ans` vector.
226+
- This effectively constructs the vertical order of the binary tree.
221227

222-
14. **Print Node Values for Each Vertical**
228+
13. **Return the Result**
223229
```cpp
224-
for (int value : pair.second) {
225-
cout << value << " ";
230+
return ans;
226231
}
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.
232+
};
233+
```
234+
- Finally, returns the `ans` vector containing the vertical order traversal of the binary tree.
231235

236+
```
237+
### Example
232238
233-
## Step 4: Output Examples with Explanation
239+
Given the following binary tree:
234240
235-
### Example 1
236-
Given the tree:
237241
```
238242
1
239243
/ \
240244
2 3
241245
/ \ \
242246
4 5 6
243-
/
244-
7
245247
```
246248
247-
**Output**:
248-
```
249-
4
250-
2
251-
1 5 7
252-
3
253-
6
254-
```
249+
The vertical order traversal would be: `4 2 1 5 3 6`.
255250
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`.
251+
1. **Horizontal distances:**
252+
- `2` has HD `-1`, `1` has HD `0`, `3` has HD `1`.
253+
- `4` has HD `-2`, `5` has HD `0`, `6` has HD `1`.
262254
263-
### Example 2
264-
For a single node tree:
265-
```
266-
1
267-
```
255+
2. **Levels:**
256+
- The levels of nodes are considered while traversing to maintain the order when nodes have the same HD.
268257
269-
**Output**:
270-
```
271-
1
272-
```
258+
### Time Complexity
273259
274-
### Explanation
275-
- The tree consists only of the root node, which is also the only node at HD `0`.
260+
- **BFS Traversal:** Each node is processed once, leading to a time complexity of **O(N)**, where **N** is the number of nodes in the tree.
276261
277-
## Step 5: Time and Space Complexity
262+
- **Map Operations:** The operations on the map also take **O(N)** time in the worst case for insertion and retrieval.
278263
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.
264+
Overall, the time complexity is **O(N)**.
283265
284266
### 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.
288267
289-
Thus, the space complexity is **O(n)** in the worst case due to storing nodes in the map.
268+
- **Queue Space:** The queue can hold at most **O(N)** nodes in the worst case (e.g., a completely unbalanced tree).
269+
270+
- **Map Space:** The map stores each node, leading to an additional **O(N)** space.
271+
272+
Overall, the space complexity is **O(N)** due to the space needed for the queue and the nested map.
290273
291-
### Summary
292-
- **Time Complexity**: **O(n)**
293-
- **Space Complexity**: **O(n)**
274+
### Conclusion
294275
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!
276+
The code effectively utilizes a queue for level-order traversal and a nested map to organize nodes by their vertical order, considering both horizontal distance and level to provide a well-structured output. If you have further questions or need clarifications, feel free to ask!

0 commit comments

Comments
 (0)