-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding Trees to Java: Data Structures (#323)
* first pass writing section on trees * using better way to hide the solution for trees * emphasis on celebrating student success * adding in picture and gif * adding in suggestions from PR
- Loading branch information
Showing
6 changed files
with
131 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,7 @@ | ||
--- | ||
title: "Trees" | ||
weight: 8 | ||
draft: false | ||
--- | ||
|
||
One more important data structure that is used in the development of other data structures and not easily seen is a **Tree**. There are many different types of trees each with their own unique purpose that you will find in differente areas across programming and computer science. Let's learn a little bit more about this behind-the-scenes data structure! |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,31 @@ | ||
--- | ||
title: "Introduction" | ||
date: 2022-08-06T13:24:17-07:00 | ||
draft: false | ||
weight: 1 | ||
--- | ||
|
||
Trees are made up of two components: **edges** and **nodes**. Let's take a look at each of these components in a bit more detail. | ||
|
||
### Edges | ||
|
||
You can imagine an edge as the line that connects two nodes. Edges always connect exactly two nodes. Edges can carry some information, but they don't need to. | ||
|
||
### Nodes | ||
|
||
Nodes are just points on a tree that represent some data. A tree needs at least one node and each node can have as many edges as it wants, as long as there is another different node that it is connected to. | ||
|
||
### Why Trees? | ||
|
||
Trees are very simple data structures that can store a lot of data while still allowing you to find it quickly. Many algorithms that rely on finding the best match organize their data in a tree before searching to optimize their speed. Some examples of trees being used in the real world include: | ||
* <a href="https://en.wikipedia.org/wiki/Spanning_Tree_Protocol" target="_blank">Spanning Tree Protocol</a> - A protocol foundational to using the Internet, | ||
* <a href="https://en.wikipedia.org/wiki/Binary_search_algorithm" target="_blank">Binary Search</a> - One of the most efficient algorithms to search for data in a sorted set, | ||
* <a href="https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html" target="_blank">TreeMaps</a> - The sibling to the HashMap data structure in Java that uses a tree to organize the data | ||
|
||
Some trees have more specific rules about how data is added to them and how the data inside is maintained, which means that there is almost always a tree ready for any scenario. | ||
|
||
## Visualizing Trees | ||
|
||
Trees will have what is called a **root node**, which is the node where the rest of the tree connects to, either directly or indirectly. We call this data structure a tree because nodes branch off of the root node. When you see a tree drawn, you will usually see the root node at the top, but that won't always be the case! | ||
|
||
![image](../img/tree.png) |
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,52 @@ | ||
--- | ||
title: "Methods" | ||
date: 2022-08-06T13:24:17-07:00 | ||
draft: false | ||
weight: 2 | ||
--- | ||
|
||
## Binary Trees | ||
|
||
Trees are a special type of data structure because they are made up of a collection of nodes connected by edges. There isn't a one stop initializer to create a new, generic tree like the other data structures we've looked at. To make things easier, we will look specifically at **Binary Trees**, which are a specific type of tree with strict rules about where each node should go. | ||
|
||
The rules for a binary tree are: | ||
* each node has exactly two edges, a left node and a right node | ||
* nodes to the left are less than the current node | ||
* nodes to the right are greater than the current node | ||
|
||
The tree we looked at before is an example of a binary tree. Take a look at each of the nodes and check for yourself that they follow the rules! | ||
![image](../img/tree.png) | ||
|
||
## Searching Elements | ||
|
||
Before we look at the implementation of how to search with code, let's look at how a binary tree might search for an element. When we are examining the elements within a tree, we always start at the root node, which in a binary tree should be more or less the middle of the data. | ||
|
||
Once we start at the root, we examine the value and ask ourselves "is the value we are looking for less than, equal to, or greater than this value?" If the value is equal, great! We found our answer. If the value we want is less than what we currently have, then we go the left node and ask ourselves the same question. If the value we want is greater than what we currently havbe, then we go to the right node and ask ourselves the same question. | ||
|
||
See if you can follow along with this example below. This is the same tree as before and we want to find the value 9. | ||
|
||
![image](../img/binarysearch.gif) | ||
|
||
## Traverse Elements | ||
|
||
Now that we conceptually understand searching for elements, we can see that searching for elements is just repeating the same operation over and over again. This means that if we program the operation correctly, the entire search algorithm is done. | ||
|
||
Imagine we have nodes that are defined like below: | ||
```js javascript | ||
class Node { | ||
int value; | ||
Node left; | ||
Node right; | ||
} | ||
``` | ||
|
||
We now can apply the logic for finding the right element that we talked about in the section above. Consider this code snippet: | ||
```js javascript | ||
Node current = root; | ||
if (current.value < desired) { | ||
current = root.right; | ||
} else if (current.value > desired) { | ||
current = root.left; | ||
} | ||
``` | ||
We can see that this takes us from one step to the next, we could then use this logic in a `for` loop until we find the value we want. |
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,41 @@ | ||
--- | ||
title: "Problem 1: Tree Basics" | ||
date: 2022-08-06T13:24:17-07:00 | ||
draft: false | ||
weight: 3 | ||
--- | ||
|
||
## Task 1: Find a Value in a Binary Tree | ||
|
||
Now that we know the basics of traversing through a tree, implement binary search based on the process (or algorithm) we talked about in the previous page. Here's a quick refresher: | ||
* If the current value is less than what we want, go to the right node. | ||
* If the current value is more than what we want, go to the left node. | ||
* If the current value is what we want, you're done! | ||
|
||
<iframe height="800px" width="100%" src="https://replit.com/@nuevofoundation/BinarySearch?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe> | ||
|
||
{{% showanswer "SPOILER: Click here if you need help with the solution!" %}} | ||
```js javascript | ||
public static Node findValue(Node root, int value) { | ||
// We start at the root of the tree | ||
Node current = root; | ||
// We follow the logic we described above | ||
while (current.value != value) { | ||
System.out.println("current value is: " + current.value); | ||
if (value < current.value) { | ||
current = current.left; | ||
} | ||
if (value > current.value) { | ||
current = current.right; | ||
} | ||
} | ||
// If we are here, we reached the node with | ||
// the correct value! | ||
return current; | ||
} | ||
``` | ||
{{% /showanswer %}} | ||
|
||
### Congrats! If you've made it this far, then you have officially programmed binary search! |