How I visualize data structures

Data structures are objects that can be used to store data in various ways based on how we need to interact with the data that’s being stored in them.

For instance, a set is an object with properties that only appear once — you might use sets to count all the unique letters that appear at least once in a string without counting whether those letters are repeated. A tree is an object that contains some data properties and a children property that contains an array of objects with a similar structure as their parent object and that may have their own children — kind of like looking at a family tree that starts with info on a grandparent, then also lists info for that person’s children and grandchildren.

If you’re completely new to data structures as I was, a lot of what you see in terms of visualizing those structures probably looks something like this one for a singly-linked list:

Source: Wikipedia

Here, we can see that the structure of a linked list includes a list of nodes that start at one number and “point” to the next number in the list. Unlike an array, data in a linked list isn’t arranged by numerical indices; you find data in the singly-linked list by following a trail that begins with the list’s “head” node, then following the “next” property of each node in order to determine which value comes after the current node. The last node in the singly-linked list is considered the “tail” of the list, which has a “next” value of null, since it isn’t pointing to anything.

I can generally explain this type of data structure visualization now. However, when I was first encountering data structures, what really helped them “click” for me was seeing the Javascript objects that are produced when we create functions that construct data structures. As a visual learner, this helped me understand what the various parts that go into different data structures look like in actual code. So for instance, instead of the linked list visualization above, the following helped me understand how to create such a list by showing its parts:

{"head": {"value": 12, "next": {"value": 99, "next": {"value": 37, "next": null}}},"tail":{"value": 37, "next": null}}

I’m using the same values as the Wikipedia visual for a singly-linked list. Here we can see the “head” of a singly-linked list is an object that contains a “value” property of 12 and a “next” property that contains another object with our next value, 99, and points to another object with a value of 37. We also have a “tail” property in the parent object that tells us we’ve reached the end of the list when we see an object with a value of 37 and a next property set to null. The tail looks exactly like the third object that’s nested in the “head” property in the parent object. If we ever add another value to this list, it will be contained in the “next” property for the object with a value of 37, and the tail will update to point to the latest node that we added.


I’ll do this with a few other basic data structures. First, let’s take a look at sets, which only count a value once and don’t account for repeat values. We can see how this works by creating a set of the letters in my name, Sheena. I have two e’s in my name, but the set will only tell us whether that letter appears at all in Sheena, not how many times. It does this by having a value of true for each property that’s already been accounted for.

{"S": true, 
"h": true,
"e": true,
"n": true,
"a": true}

Now let’s take a look at trees as I’ve described them above in terms of a family tree (I’ll get into binary search trees next). The code structure of a standard tree — which includes arrays of child nodes — might look like this:

{"value": "Grandparent", "children": [{"value": "Child 1", "children":[{"value": "Grandchild 1", "children":[]},                      {"value": "Grandchild 2", "children":[]}]}, {"value":"Child 2",          "children":[]}]}
//FORMATTED VERSION
{"value": "Grandparent",
"children": [
{"value": "Child 1",
"children":[
{"value": "Grandchild 1",
"children":[]},
{"value": "Grandchild 2",
"children":[]}]},
{"value":"Child 2",
"children":[]}]
}

Lastly, let’s take a look at binary search trees. These data structures allow us to sort certain data in a way that can help us find a value more quickly than something like a linked list.

If we were looking for the value 99 in the linked list above, we would have to start at the beginning of the list and look through each node until we found 99 — a method that could take quite a bit of time depending on how long our list is.

In a binary search tree, rather than searching through all values in the structure, we can narrow down the areas of the structure that we want to search based on whether the value we’re searching for is higher or lower than the current node that is being looked at. A value that is lesser than the current node goes on the left, and a value that is greater than the current node would be on the right.

A visualization of a binary search tree might look like this:

Source: Wikipedia

If we were looking for the value 6, we would start by looking at the tree’s “root” node, which has a value of 8. Since 6 is less than 8, we’ll only search on the left side of the whole tree. That brings us to the node with a value of 3. Since 6 is greater than 3, we’ll search on the right side of that node, which brings us to the node with the value we’re looking for.

Here’s what the code structure of a binary search tree would look like with the same values as the above visual:

{"value": 8, "left": {"value": 3, "left": {"value": 1, "left": null, "right": null}, "right": {"value": 6, "left": null, "right": null}}, "right": {"value": 10, "left": null, "right": {"value": 14, "left": null, "right": null}}}
//FORMATTED VERSION
{"value":8,"left": 
{"value":3,"left":
{"value":1,"left":null,
"right":null},
"right":
{"value":6,"left":null,
"right":null}},
"right":{"value":10,"left":null,
"right":
{"value":14,"left": null,
"right": null}}}

As you can see, the nodes in the binary search tree code structure are set to properties labeled “left” and “right” based on the comparison of the new node and the nodes on each level of the current true. The nodes at the bottom level of the tree have null “left” and “right” values.