Data Structures and Algorithms Teaching

Data Structures and Algorithms Teaching

Other teaching team members: Megan Ku, Dieter Brehm, Jane Sieving | Faculty Advisors: Stephanos Matsumoto, Linda Vanasupa


In the spring of 2021, three fellow Olin students and I taught a student-led data structures and algorithms (DSA) course under the course name ENGR3599: Special Topics in Computing.

Guided by two faculty advisors and receiving credit for the experience via an independent study in pedagogy, the four of us led development of the course’s curriculum (derived from the DSA courses we took), ran all classes, authored homework assignments and lecture materials, coordinated a team of seven course assistants, and guided students in their class projects.

Course Design and Content

From a student learning outcome perspective, the guiding goal was for our students to:

Become fluent with foundational data structures and algorithmic concepts and know when and how to apply them to solve more complex problems.

From a class content delivery perspective, we used three different modes:

  1. Interactive lectures (interactive in that we often asked questions of our audience) delivered by at least two instructors.
  2. Planned group work (in breakout rooms) on problems interspersed within lectures.
  3. Static content reference pages for every class; these reference pages at minimum included links to external resources on the covered content, and sometimes were themselves standalone summaries of the topics.

Classes I Co-taught

  • Introduction to Algorithm Analysis and Asymptotic Growth
  • Amortized Analysis
  • Heaps and Priority Queues
  • Graphs: Introduction, Depth-First Search, and Breadth-First Search
  • Dynamic Programming
  • Dijkstra’s and Bellman-Ford’s Algorithms
  • A* Search
  • Greedy and Heuristic Algorithms
  • Complexity Classes (an overview)

For a subset of these classes, I also took responsibility for associated homework assignment authoring and lecture material creation.

A screenshot of the lecture in which I was explaining the Dynamic Programming (DP) solution to the knapsack problem (with integer weights).

Key Takeaways

A deeper knowledge of computer science

When planning the class content for a particular topic, I always started by seeking out additional information on that topic that expanded my understanding of the topic.

For example, when preparing for teaching the classes on dynamic programming, I first spent extensive time refreshing my knowledge on the related topic of backtracking that was covered in the previous class. I then constructed the dynamic programming lesson to begin by illustrating how backtracking improves the average case runtime (but not upper bound runtime) when compared to brute force.

Then, having introduced backtracking as an approach to avoid branches of the search tree that are infeasible, I introduced the concept of dynamic programming as an extension backtracking: that it not only avoided infeasible branches, but also avoided exploring identical branches.

This approach to introducing dynamic programming was different than how it was taught to me in that it more closely related dynamic programming to a previously covered topic; it also helped me appreciate dynamic programming from a different perspective.

An important lesson in teaching

An important element of our classes were the problems that we prescribed for group work because they gave students a chance to grapple with new concepts instead of just consuming them in lecture. This interweaving of group work with lectures is commonplace at Olin, and is something that my co-instructors and I adopted naturally into the course.

Something I well understood going into this teaching experience is that a more effective way to help a student struggling to understand something than simply sharing the solution is to ask probing questions that, when answered by the student, help connect the dots in their own understanding. However, in situations where group work concluded with several of the ~25 students still struggling to solve the problem, I found that my default response was to share the answer to the problem and then move on to the next topic.

Though going to every student and asking probing questions would be infeasible given the time constraints, I realized through reflection that the class would have been better served if I had preceded my sharing of the answer with some time spent diagnosing what the collective confusion was. This is a lesson that I will carry with me into any future scenario where I am teaching a new concept.