-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
728 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
## Tress - A hierarchical Data Struture | ||
|
||
Trees are hierarchical data structures consisting of nodes. | ||
|
||
A tree consits of root node, parent nodes, children nodes, leaf-nodes, sub-tree and ancestors. | ||
|
||
``` | ||
1 <-- root node | ||
/ \ | ||
2 3 <-- Child node | ||
/ \ / \ | ||
4 5 6 7 | ||
/ / \ | ||
8 9 10 <-- Leaf node | ||
``` | ||
|
||
--- | ||
|
||
### Binary Search Tree | ||
|
||
A Binary tree is a type of tree where each parent node consists of at **max 2** child nodes. | ||
|
||
**Types of Binary tree :** | ||
|
||
1. **Fully Binary tree :** Every node will either have 0 or 2 children nodes. | ||
|
||
2. **Complete Binary Tree :** All levels of tree should be completely filled. If not completely filled, then the last level should have all nodes as left as possible. | ||
|
||
3. **Perfect Binary Tree :** All leaf nodes are at same level. | ||
|
||
4. **Blnced Binary Tree :** The tree can at max have a height of **Log<sub>2</sub>(n)**, where n is number of nodes. | ||
|
||
5. **Degenerate Tree :** When every node only have a single child or parent node. This type resembles to a Linked List. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
## Representation of a Tree in C++ | ||
|
||
``` | ||
1 <-- data | ||
left pointer --> / \ <-- right pointer | ||
2 3 | ||
/ \ | ||
4 NULL | ||
``` | ||
|
||
--- | ||
|
||
### Implementation : | ||
|
||
```cpp | ||
struct Node { | ||
int data; | ||
struct Node *left; | ||
struct Node *right; | ||
// constructor | ||
Node(int value){ | ||
data = value; | ||
left = right = NULL; // initially pointing to null | ||
} | ||
} | ||
|
||
// Tree Creation | ||
int main() { | ||
// calling constructor and passing root's value. | ||
struct Node *root = new Node(1); | ||
|
||
root->left = new Node(2); | ||
root->right = new Node(3); | ||
|
||
root->left->left = new Node(4); | ||
|
||
return 0; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
## Traversing in a Tree | ||
|
||
There are two ways to traverse in a Binary search tree : | ||
|
||
1. **Depth-First-Search [DFS] :** | ||
In this method, the tree is traversed through it's entire height / length. | ||
|
||
There are 3 types of DFS :- | ||
|
||
a. _In-order Traversal_ (left-**root**-right) : Start form the root, if there exists a left, go left, if no further left, print left, go back, print the root and now look for right, if right exists, apply the same logic. | ||
|
||
``` | ||
1 | ||
/ \ | ||
2 3 | ||
/ \ / \ | ||
4 5 6 7 | ||
/ / \ | ||
8 9 10 | ||
``` | ||
|
||
In above BST, if we apply In-order traversal, we get : | ||
|
||
``` | ||
4 2 8 5 1 6 3 9 7 10 | ||
``` | ||
|
||
--- | ||
|
||
b. _Pre-Order-Traversal_ (**root**-left-right) : Start from the root, print root, if left exists, go left & print left, if no further left, go back, check for right, if right exists, apply the same logic. | ||
|
||
In above BST, if we apply Pre-order traversal, we get : | ||
|
||
``` | ||
1 2 4 5 8 3 6 7 9 10 | ||
``` | ||
|
||
--- | ||
|
||
c. _Post-Order-Traversal_ (left-right-**root**) : Start from the root, if left exists, go to left, print left, if no further left, go back, check if right exists, if exists print right, go back and print root. | ||
|
||
In above BST, if we apply Pre-order traversal, we get : | ||
|
||
``` | ||
4 5 8 2 6 7 9 10 7 3 1 | ||
``` | ||
|
||
--- | ||
|
||
2. **Breadth-first-Search [BFS] :** In this method, we traverse the tree level by level, through it's entire breadth. | ||
|
||
``` | ||
--> 1 | ||
/ \ | ||
--> 2 3 | ||
/ \ / \ | ||
--> 4 5 6 7 | ||
/ / \ | ||
--> 8 9 10 | ||
``` | ||
|
||
**BFS in Above Tree :** | ||
|
||
``` | ||
1 2 3 4 5 6 7 8 9 10 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
## In-Order-Traversal ~ Recursive approach C++ Implementation | ||
|
||
``` | ||
1 | ||
/ \ | ||
2 3 | ||
/ \ / \ | ||
4 5 6 7 | ||
/ / \ | ||
8 9 10 | ||
``` | ||
|
||
### Implemantation : | ||
|
||
```cpp | ||
void inorder(int node){ | ||
if (node == NULL) { // base case | ||
return; | ||
} | ||
inorder(node->left); // recursion | ||
cout << node->data << endl; | ||
inorder(node->right); // recursion | ||
} | ||
``` | ||
pattern : left --> print --> right |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
## Pre-Order-Traversal ~ Recursive approach C++ Implementation | ||
|
||
``` | ||
1 | ||
/ \ | ||
2 3 | ||
/ \ / \ | ||
4 5 6 7 | ||
/ / \ | ||
8 9 10 | ||
``` | ||
|
||
### Implemantation : | ||
|
||
```cpp | ||
void preorder(int node){ | ||
if (node == NULL) { // base case | ||
return; | ||
} | ||
cout << node->data << endl; | ||
preorder(node->left); // recursion | ||
preorder(node->right); // recursion | ||
} | ||
``` | ||
pattern : print --> left --> right |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
## Post-Order-Traversal ~ Recursive approach C++ Implementation | ||
|
||
``` | ||
1 | ||
/ \ | ||
2 3 | ||
/ \ / \ | ||
4 5 6 7 | ||
/ / \ | ||
8 9 10 | ||
``` | ||
|
||
### Implemantation : | ||
|
||
```cpp | ||
void postorder(int node){ | ||
if (node == NULL) { // base case | ||
return; | ||
} | ||
postorder(node->left); // recursion | ||
postorder(node->right); // recursion | ||
cout << node->data << endl; | ||
} | ||
``` | ||
pattern : left --> right --> print |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
## Level Order Traversal [BFS] C++ Implementation | ||
|
||
==> We'll need two data sructures, A queue and a vector of vectors. | ||
|
||
--> The Queue will hold the roots of tree. | ||
|
||
--> vector will hold the levels | ||
|
||
Step 1 : Push the root node of the tree to the queue. | ||
|
||
Step 2: Check if there exists any left or right branch for that node. | ||
|
||
Step 3: If there exists any left or right, push them to queue. | ||
|
||
Step 4: Once performed Step 2 & 3 for a node, push that node into the vector. | ||
|
||
Step 5 : Now iterate over the next queue elements and take them out, and repeat from Step 2. Check for their left and right, push their left / right to the queue and finally push the previous queue elements into the vector | ||
|
||
--- | ||
|
||
Example : | ||
|
||
``` | ||
--> 1 | ||
/ \ | ||
--> 2 3 | ||
/ \ / \ | ||
--> 4 5 6 7 | ||
``` | ||
|
||
Step 1 : | ||
|
||
The queue becomes : | ||
|
||
``` | ||
1 | ||
``` | ||
|
||
Step 2, Step 3 : Root node 1 has child nodes 2 and 3 as it's left and right, so push them to the queue. | ||
|
||
The queue becomes : | ||
|
||
``` | ||
1 2 3 | ||
``` | ||
|
||
Step 4 : | ||
|
||
Push Root node 1 into the vector. | ||
|
||
The vector becomes : | ||
|
||
``` | ||
1 | ||
``` | ||
|
||
Step 5 : | ||
|
||
Once we've performed these operations for Node 1, take child node 2 and 3 out of the queue and check if they have any left / right child nodes. | ||
|
||
2 and 3 have 4 5 6 7 as their child nodes, push them to the queue. | ||
|
||
The queue becomes : | ||
|
||
``` | ||
1 2 3 4 5 6 7 | ||
``` | ||
|
||
Now Push the child nodes 2 & 3 into the vector. | ||
|
||
The vector becomes : | ||
|
||
``` | ||
1, 2 3 | ||
``` | ||
|
||
Once we've performed these operations for Child nodes 2 & 3, take child node 4, 5, 6 and 7 out of the queue and check if they have any left / right child nodes. | ||
|
||
4 5 6 7 doesn't have any child nodes to push into the queue, so push them to the vector | ||
|
||
The vector becomes : | ||
|
||
``` | ||
1, 2 3, 4 5 6 7 | ||
``` | ||
|
||
**So the Level order traversal prints `1 2 3 4 5 6 7`** | ||
|
||
--- | ||
|
||
![Visualization](https://github.com/Rishabh672003/Programming-Notes/assets/53911515/596d45d5-7510-4b23-946b-215811a55ab0) | ||
|
||
--- | ||
|
||
### Approach : | ||
|
||
- Declare a vector of vectors (ans). | ||
- if root == NULL, return ans. | ||
- declare a queue, push the root into it. | ||
- while the queue is not empty, | ||
- calculate it's size to traverse. | ||
- declare a vector to store levels (levels). | ||
- traverse the current nodes inside the queue. | ||
- declare a node and initialize it to q.front(). | ||
- pop the node out of the queue and check if it's left and right exists. | ||
- If exists, push them to queue | ||
- push the node's value into the (level) vector. | ||
- push the (level) vector to (ans) vector. | ||
|
||
--- | ||
|
||
### Implementation : | ||
|
||
```cpp | ||
/* Defination for binary tree : | ||
struct TreeNode { | ||
int val; | ||
TreeNode *left; | ||
TreeNode *right; | ||
TreeNode() : val(x), left(nullptr), right(nullptr) {} | ||
TreeNode(int x): val(x), left(nullptr), right(nullptr) {} | ||
TreeNode(int x, TreeNode *left, TreeNode *right): val(x), left(left), right(right) {} | ||
} | ||
*/ | ||
|
||
class Solution { | ||
public: | ||
vector<vector<int>> levelOrder(TreeNode *root){ | ||
vector<vector<int>> ans; // vector of vector | ||
if (root == NULL) return ans; | ||
queue<TreeNode*> q; // queue | ||
q.push(root); | ||
while(!q.empty()){ | ||
int size = q.size(); | ||
vector<int> level; | ||
for (int i = 0; i < size; i++){ | ||
TreeNode *node = q.front(); | ||
q.pop(); | ||
if (node->left != NULL) q.push(node->left); | ||
if (node->right != NULL) q.push(node->right); | ||
level.push_back(node->value); | ||
} | ||
ans.push_back(level); | ||
} | ||
return ans; | ||
} | ||
}; | ||
``` |
Oops, something went wrong.