Skip to content

Commit 49e4587

Browse files
authored
Update trees.txt
1 parent c9edcdc commit 49e4587

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

slides/graphtheory/trees.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ We now know what trees are, but where do they appear in computer science and in
2525

2626
Now we need to talk about how we actually store and represent these undirected trees.
2727

28-
First, you will need to label the nodes of your tree by indexing it, preferably from 0 to n non-inclusive like the one on the left of this slide.
28+
First, you should label the nodes of your tree by indexing them from 0 to n non-inclusive like the tree on the left of this slide.
2929

3030
A simple way to store a tree is as an edge list, which is simply a list of undirected edges indicating which two nodes have an edge between them. The great thing about this representation is that it's super fast to iterate over and cheap to store.
3131

3232
The downside however, is that storing your tree as a list lacks the structure to efficiently query all the neighbors of a node.
3333

34-
This is why the adjacency list is usually a more popular representation to store an undirected tree. In this representation, you store a mapping between a node and all its neighbors.
34+
This is why the adjacency list is usually a more popular representation for storing an undirected tree. In this representation, you store a mapping between a node and all its neighbors.
3535

3636
For example, node 4 has the neighbors 1, 5 and 8 so in the adjacency list, node 4 maps to the list containing 1, 5 and 8 respectively.
3737

@@ -40,25 +40,25 @@ You could also store a tree as an adjacency matrix of size n by n where having a
4040
However, in practice I would say to always avoid storing a tree as an adjacency matrix because it's a huge waste of space. You would not ever want to allocate n squared memory and only use roughly 2n of the matrix cells, it just doesn't make sense.
4141

4242

43-
Alright, I can't keep talking about trees without mentioning rooted trees which are trees with a designated root node. I have highlighted the root node in orange, and most rooted trees as you'll notice have directed edges which point away from the root node, however it's also possible to have edges which point towards the root node, but those trees are much rarer in my experience.
44-
Generally speaking, rooted trees are far easier to work with than undirected trees because they have a well defined structure and allow for recursive algorithm implementations.
43+
Alright, I can't keep talking about trees without mentioning rooted trees which are trees with a designated root node. I have highlighted the root node in orange, and most rooted trees as you'll notice have directed edges which point away from the root node, however it's also possible to have edges which point towards the root node, but those trees are much rarer from my experience.
44+
Generally speaking, rooted trees are far easier to work with than undirected trees because they have this well defined structure that allows for easy recursive algorithm implementations.
4545

4646
Related to rooted trees are binary trees which are trees for which every node has at most two child nodes. The first two trees on this slide are binary trees, but the last one is not because it has a node with more than 2 child nodes.
4747
You don't often see binary trees manifest themselves in the real world, for the most part binary trees are artificially created and integrated as part of data structures to guarantee efficient insertions, removals and access to data.
4848

4949
Now related to binary trees are binary search trees which are trees which satisfy the BST invariant. The BST invariant states that for every node x the values in the left subtree are less than or equal to x and that the values in the right subtree are greater than or equal to x. This nice little property enables you to quickly search through a tree and retrieve the values you want, which is particularly handy. All the trees on this slide are BSTs except for the last one, because 1 is *not* greater than or equal to 3.
5050

51-
It's often useful to require uniqueness on the values of your tree so that you don't end up with duplicate values in the tree. To resolve this issue of duplicate values you can change the invariant to be strictly less than rather than less than or equal to.
51+
It's often useful to require uniqueness on the values of your binary search tree so that you don't end up with duplicate values. To resolve this issue of duplicate values you can change the invariant to be strictly less than rather than less than or equal to.
5252

5353
Now let's talk about how to store these rooted trees. Rooted trees are naturally defined recursively in a top down manner.
5454

5555
In practice, you always maintain a pointer reference to the root node so that you can access the tree and its contents.
5656

5757
Then each node also has access to a list of all its children -- which are also called "child nodes". In this slides, the orange node is the current node we have a reference to, and the purple nodes are all its children. All the bottom or leaf nodes don't have any children.
5858

59-
It's also sometimes useful to also maintain a pointer to a node’s parent node in case you need to traverse up the tree. This effectively makes the edges in the tree bidirectional. Again, if the current node is the orange node, than the pink node in the case in the parent node.
59+
It's also sometimes useful to also maintain a pointer to a node’s parent node in case you need to traverse up the tree. This effectively makes the edges in the tree bidirectional. Again, if the current node is the orange node, than the pink node in the case in the parent node of the orange node.
6060

61-
However, maintaining an explicit reference to the parent node isn’t usually necessary because you can access a node’s parent on a recursive function's callback.
61+
However, maintaining an explicit reference to the parent node isn’t usually necessary because you can access a node’s parent on a recursive function's callback as you pop frames off the stack.
6262

6363

6464
Another really neat way of storing a rooted tree if it is a binary tree is in a flattened array.
@@ -72,7 +72,7 @@ mapped back to a unique position in the "index tree" as I call it.
7272

7373
In this format, the root node is always at index 0 in the array, so you always know where your starting point is. Another advantage of this format is that the child nodes of node i can be access relative to position i.
7474

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.
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.
7676

7777
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.
7878

0 commit comments

Comments
 (0)