A Great Visual Studio Code Extension to help you learn Data Structures Visually
Image Cover by Chinenye Okeke
I recently stumbled across a short from the official "Visual Studio Code" Channel where they showcase an extension called "Debug Visualizer". It is essentially allows you to see your Data Structures in a visual format without having yourself to imagine it. I found it to be a great way for people, like me, to practice my Data Structures and Algorithms for technical interviews because I master topics quickly when it comes to visual learning.
Trying out the tool myself!
I want to see how good it is, so I tried the extension. It was quite difficult to set up since there were limited documentation. With the help of AI, I was able to get an MVP. The example I am showcasing is reversing a Linked List:
from __future__ import annotations
from dataclasses import dataclass
from typing import Optional, Iterable, Any
import json
try:
import debugpy # VS Code debugging adapter
except Exception: # pragma: no cover - defensive fallback
debugpy = None
@dataclass
class Node:
value: Any
next: Optional["Node"] = None
class LinkedList:
def __init__(self, values: Optional[Iterable[Any]] = None):
self.head: Optional[Node] = None
if values:
for v in values:
self.insert_tail(v)
def insert_tail(self, value: Any) -> None:
if not self.head:
self.head = Node(value)
return
cur = self.head
while cur.next:
cur = cur.next
cur.next = Node(value)
def reverse_iterative(
self,
pause_each_step: bool = False,
update_head_during_reverse: bool = True,
) -> None:
prev, cur = None, self.head
while cur:
nxt = cur.next
cur.next = prev # <-- pointer mutation (reverse one link)
prev = cur
# Let ll.head reflect the reversed prefix in real time (useful for visualize_ll(ll.head)).
if update_head_during_reverse:
self.head = prev
# Pause so the Debug Visualizer can be refreshed on this state.
if pause_each_step and debugpy is not None:
debugpy.breakpoint()
cur = nxt
self.head = prev
# Optional niceties for quick console inspection
def __iter__(self):
cur = self.head
while cur:
yield cur.value
cur = cur.next
def __repr__(self):
return "LinkedList([" + ", ".join(map(str, self)) + "])"
def visualize_ll(head: Optional[Node]) -> str:
nodes, edges, visited = [], [], set()
cur = head
while cur and id(cur) not in visited:
visited.add(id(cur))
nid = str(id(cur))
nodes.append({"id": nid, "label": str(cur.value)})
if cur.next is not None:
edges.append({"from": nid, "to": str(id(cur.next)), "label": "next"})
cur = cur.next
return json.dumps({
"kind": {"graph": True},
"nodes": nodes,
"edges": edges
})
def visualize_reverse_state(prev: Optional[Node], cur: Optional[Node]) -> str:
nodes = [
{"id": "ENTRY_PREV", "label": "reversed head (prev)", "color": "green"},
{"id": "ENTRY_CUR", "label": "remaining head (cur)", "color": "orange"},
]
edges = []
visited = set()
def add_chain(head: Optional[Node], entry_id: str, color: str):
nonlocal nodes, edges, visited
if head is None:
# Show a 'None' target for clarity
null_id = f"{entry_id}_None"
nodes.append({"id": null_id, "label": "None", "color": color})
edges.append({"from": entry_id, "to": null_id, "label": "head"})
return
edges.append({"from": entry_id, "to": str(id(head)), "label": "head"})
cur = head
while cur and id(cur) not in visited:
visited.add(id(cur))
nid = str(id(cur))
nodes.append({"id": nid, "label": str(cur.value), "color": color})
if cur.next is not None:
edges.append({"from": nid, "to": str(id(cur.next)), "label": "next"})
cur = cur.next
add_chain(prev, "ENTRY_PREV", "green")
add_chain(cur, "ENTRY_CUR", "orange")
return json.dumps({
"kind": {"graph": True},
"nodes": nodes,
"edges": edges
})
if __name__ == "__main__":
ll = LinkedList([3, 1, 4, 1, 5, 9])
print("Before:", ll)
ll.reverse_iterative(pause_each_step=True, update_head_during_reverse=True)
print("After: ", ll)
Now the magic happens. I put the code into my Visual Studio Code to see how it would look like. Here are the steps to get it working:
- Make sure you "run and debug" the python file instead of simply running the file.
- Go to "Command Palette" and search
> Debug Visualizer: New View. It will open a split window. - Then, copy/paste into the field Debugging Viewer "visualize_ll(ll.head)" for this example. Then, press "continue" on the debugging section to see it change in real time!
Here is the full demonstration of it in detail:
{% embed https://www.youtube.com/shorts/3O6BFlOiFRg %}
I found this to be a great tool overall! I wish there were documentation in detail on setting it up, but it was quite limited. Initially, I thought it would be as simple as "list = [1,2,3]" but there is more to set up. If you would like to check it out the extension, here is the link for more information: Debug Visualizer for Visual Studio Code
Discussion Questions
- What do you think of this great extension tool?
- Have you heard of this tool before? Regardless if you have heard it or not, are you planning on using it?
- If you used it before, what was your experience?
Question/Comments? I would love to hear from you!