Skip to content

Commit

Permalink
Adding Trees to Java: Data Structures (#323)
Browse files Browse the repository at this point in the history
* 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
edengarza authored Sep 20, 2024
1 parent 0bb7bc9 commit eeac7dc
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 0 deletions.
7 changes: 7 additions & 0 deletions content/english/java-datastructures/trees/_index.md
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.
31 changes: 31 additions & 0 deletions content/english/java-datastructures/trees/introduction.md
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)
52 changes: 52 additions & 0 deletions content/english/java-datastructures/trees/methods.md
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.
41 changes: 41 additions & 0 deletions content/english/java-datastructures/trees/problem-1.md
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!

0 comments on commit eeac7dc

Please sign in to comment.