You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: slides/graphtheory/trees.txt
+38-31Lines changed: 38 additions & 31 deletions
Original file line number
Diff line number
Diff line change
@@ -74,30 +74,32 @@ In this format, the root node is always at index 0 in the array, so you always k
74
74
75
75
For example, if we're at position 2 in the array, we know that the left and right children of the node at index 2 is given by 2 times i plus 1 and 2 times i plus 2. Therefore the children of the node at index 2 can be found at positions 5 and 6. Reciprocally, this means if we have a node we know what the index of the parent node should be which is also very useful.
76
76
77
+
Alright, that's all I have for this video, thank you for watching, please like and subscribe and I'll see you in the next one.
Hello and welcome, my name is William, and in today's video we're going to look at some simple tree algorithms. This video is aimed at all you beginner's just starting computer science who are still learning how to write recursive code.
88
+
We're going to have a look at two pretty classic problems today, these are the types of problems you might encounter as warm up problems in an interview.
88
89
89
90
<problem1>
90
-
Alright, I want to start looking at how to write some useful tree algorithms.
91
-
For this first problem, let's find the sum of all the leaf nodes of a tree.
91
+
Alright, let's start with our first problem. For this problem we need to find the sum of all the leaf node values in a tree.
92
92
93
-
So given a tree such as this one we want to sum up all the bottom node values
93
+
For instance, given this tree we want to sum up all the bottom nodes which have no children.
94
94
95
-
That would be all these nodes in red for a total of 9. If you're keen you can
95
+
That would be all these nodes in red for a total of 9. If you're keen, you can
96
96
pause this video and give it a try.
97
97
98
98
<press>
99
99
100
-
Like all rooted tree problems we start with a reference to the root node. To solve this problem all we need to do is perform a tree traversal and identify leaf nodes while we do the traversal. It's pretty simple, watch how the animation does it.
100
+
Like all rooted tree problems we start with a reference to the root node. To solve this problem all we need to do is perform a tree traversal and identify leaf nodes while we do the traversal.
101
+
Two popular traversal algorithms are doing a Breadth First Search and Depth First Search. On trees, the preferred traversal method is typically a DFS because it lends itself to be easily implemented recursively.
102
+
It's pretty simple, watch how the animation does it. You start at the root and plunge down the tree depth first.
101
103
102
104
<do animation>
103
105
@@ -111,42 +113,42 @@ For example, if we're at position 2 in the array, we know that the left and righ
111
113
112
114
The next thing we do is check if the current node is a leaf node, and if it is we return the value stored in the leaf node.
113
115
114
-
The isLeaf method checks if a node is a leaf node by counting all its children. If the number of child nodes is zero then we know the node is a child node.
116
+
The isLeaf method checks if a node is a leaf node by counting all its children. If the number of child nodes is zero then we know the node is a leaf node.
115
117
116
-
If the node is node a leaf node then we iterate over all the children and all the leafSum method recursively summing over the return values. This ensures that we traverse the entire tree and properly accumulate values.
118
+
If the node is not a leaf node then we iterate over all the children and call the leafSum method recursively summing over the return values. This ensures that we traverse the entire tree and properly accumulate values.
117
119
118
-
Finally, once we have finished computing the total for this node and its subtree return the total.
120
+
Finally, once we have finished computing the sum for this node and its subtree return the total.
119
121
120
122
And that's all for summing up the leaf node values.
121
123
</problem1>
122
124
123
125
<problem2>
124
-
Our second problem today is a classic problem in computer science which is to find the height of a binary tree. The height of a tree is defined as the number of edges from the root to the lowest leaf. So the leftmost tree has a height of zero because it has no edges, the middle tree has a height of 1 and the rightmost tree has a height of 3 because the longest path from the root to a leaf node is 3.
126
+
Our second problem today is a classic problem in computer science which is to find the height of a binary tree. The height of a tree is defined as the number of edges from the root to the lowest leaf. Here the leftmost tree has a height of zero because it has no edges, the middle tree has a height of 1, and the rightmost tree has a height of 3 because the longest path from the root to the lowest leaf is 3.
125
127
126
-
To solve this problem we're going to break it down and define a new function h of x which returns the height of the subtree rooted at node x.
128
+
To solve this problem we're going to break it down and define a new function "h of x" which returns the height of the subtree rooted at node x.
127
129
This new function allows us to start thinking not only about the height of the tree as a whole but also the height of the subtrees within our tree which are going to help us find the overall height.
128
130
129
-
For example, on this slide h of x has a value of 3, but h of b has a value of 2 and h of e has a value of zero.
131
+
For example, on this slide "h of a" has a value of 3, but "h of b" has a value of 2 and "h of e" has a value of zero.
130
132
131
133
By themselves, leaf nodes such as node e don't have children, so they don’t add any additional height to the tree. So we can conclude that as a base case the height of any leaf node should be zero.
132
134
133
-
Now, assuming node x is not a leaf node, we're able to formulate a recurrence relation for the height which is that the height of the subtree rooted at node x is the maximum of the height of x's left and right children plus one.
135
+
Now, assuming node x is not a leaf node, we're able to formulate a recurrence relation for the height, which is that the height of the subtree rooted at node x is the maximum of the height of x's left and right children plus one.
134
136
135
-
Let's look at an example of how this works. Suppose we have this tree and we want to compute its height.
137
+
Let's have a closer look at how this works with an example. Suppose we have this tree and we want to compute its height.
136
138
137
139
So we start at the root
138
140
139
141
and then we start traversing down the tree depth first
140
142
141
-
If we encounter a leaf node we mark it as having a height of zero and return
143
+
When we encounter a leaf node, we give it a height of zero and return
142
144
143
145
We can't compute the height of a node until we know the height of all its children, so we visit the right node.
144
146
145
-
The right node is also a leaf node so it has a height of zero
147
+
The right node is also a leaf node so it gets a height of zero
146
148
147
149
On the callback we have visited both children of the current node so we take the maximum heights of the left and the right children and add 1 for a total of 1.
148
150
149
-
We just finished exploring the right half of the tree, now let's finished the left side. It doesn't matter which side you do first as long as you explore the whole tree while doing your DFS.
151
+
We just finished exploring the right half of the tree, now let's finish the left side. It doesn't matter which side you do first as long as you explore the whole tree while doing your DFS.
150
152
151
153
<press>
152
154
@@ -160,15 +162,15 @@ For example, if we're at position 2 in the array, we know that the left and righ
160
162
161
163
<press>
162
164
163
-
leaf node
165
+
and another leaf node
164
166
165
167
take the max and add 1
166
168
167
169
take the max and add 1 again
168
170
169
171
finally compute the height of the final node by taking the max and adding 1
170
172
171
-
And there you have it, how the find the height of a tree. Let's have a look at some pseudocode shall we.
173
+
And there you have it, how the find the height of a tree. Let's have a look at some pseudocode, shall we.
172
174
173
175
<pause and press>
174
176
@@ -178,15 +180,16 @@ For example, if we're at position 2 in the array, we know that the left and righ
178
180
179
181
Next we check whether the current node is a leaf node by checking if both its left and right child are null and return zero. If either of them are not null then we know this node has more children and we need to keep digging down the tree.
180
182
181
-
In the event we haven't found a leaf node, return the maximum height of the left subtree and the right subtree plus 1.
183
+
In the event we haven't found a leaf node, return the maximum height of the left subtree and the right subtree plus 1. <pause>
182
184
183
-
Let's go back to the previous statement. What happens if we remove checking whether a node is a leaf node or not, would the algorithm still behave correctly? Pause the video and take a moment to think about this.
185
+
I want to take a moment and go back to the previous statement and remark on a simplification we can exploit.
186
+
What do you reckon happens if we remove checking whether a node is a leaf node or not, do you think the algorithm would still behave correctly? Pause the video and think this over.
184
187
185
-
Removing the leaf node check still makes the algorithm work correctly, but it changes the meaning of our base case. Instead of the base case checking for leaf nodes, it's now checking whether a node is null and returning -1. Returning -1 now not only checks for the empty tree case, but it also helps in correcting for the right height.
188
+
Oddly enough, removing the leaf node check still makes the algorithm work correctly. This works because the base case has adopted a new meaning, instead of the base case checking for leaf nodes, it's now checking whether a node is null and returning -1. Returning -1 now not only checks for the empty tree case, but it also helps in correcting for the right height.
186
189
187
190
Let's see what I mean by correcting for the right height. If our new base case is now checking for null nodes instead of the leaf nodes, then our tree one unit taller, so we need to correct for this.
188
191
189
-
For the sake of being through, let's see how the height is calculated with this new base case.
192
+
For the sake of being thorough, let's see how the height is calculated with this new base case.
190
193
191
194
<press>
192
195
@@ -198,21 +201,25 @@ For example, if we're at position 2 in the array, we know that the left and righ
198
201
199
202
Once we reach a null node, return -1
200
203
201
-
On the recursive callback recall that we always all +1
204
+
On the recursive callback remember that we always add +1
202
205
203
206
<press>
204
207
205
208
<press>
206
209
207
210
<press>
208
211
209
-
So when we add up the counts you see that we get the correct height of three. Effectively, returning -1 cancels itself with the leaf node's return value computing the correct number of edges for the height function.
210
-
</problem2>
212
+
So when we add up the counts, you see that we get the correct height of 3.
211
213
214
+
And that's how you compute the height of a tree. In practice, if you're designing a data structure where tree height is important you can dynamically keep track of the height as you create the tree instead of computing it fully like we're doing here, but of course, that it's always doable.
215
+
</problem2>
212
216
217
+
Alright folks, thanks for watching, please like and subscribe if you learned something and i'll catch you next time.
213
218
214
-
But why does this work? Suppose we want to find the height at node a, the root node, then we can do so by
0 commit comments