Overview

1 Starting a fabulous adventure

This chapter introduces a playful, curiosity-driven lens on algorithms and data structures—what makes them “fabulous.” The author celebrates solutions born from real problems that go off the beaten path, counterintuitive wins like embracing immutability for clarity and robustness, and patterns that transfer across domains (for example, backtracking powering search, map coloring, sudoku, and pretty printing). The joy comes from emphasizing meaning over mechanisms, marveling at “magic trick” data structures, exploiting language features to their fullest, reframing problems for dramatic speedups, connecting practice to theory, and simply having fun. The book aims to take readers beyond the standard curriculum, adding practical tools while reshaping how they think about programming.

After setting the tone, the chapter defines data structures as organized ways to store information and algorithms as finite procedures (not necessarily deterministic or computer-bound) for solving problems. Complexity measures how cost (time, memory, or other resources) grows with problem size, using Big-O notation: constant, logarithmic, linear, quasilinear, quadratic, exponential, and factorial, each illustrated with everyday tasks and cautions about “accidentally quadratic” designs. It emphasizes choosing the right notion of size (elements, height, etc.) and the right cost model (time vs. memory; best-, average-, worst-case). A key lesson: asymptotically better is not always practically better—workloads with short inputs may favor simpler algorithms despite worse worst-case bounds.

The warmup builds an immutable linked list in C#, then reverses it by iterating and pushing onto a new list—an O(n) time and space solution that preserves the original. Along the way, subtle design and performance pitfalls surface: representing emptiness safely, avoiding expensive or recursive value equality that risks stack overflows, and fixing accidentally quadratic string concatenation. The road ahead promises twists on familiar structures (stacks, queues, trees), persistence and memoization, elegant list reorderings, a startling near-constant-time reverse trick, backtracking for coloring and pretty printing, unification and anti-unification, and a final toolkit for probability and Bayesian inference, with occasional detours into the shared abstractions of category theory. Though examples use C#, the ideas generalize broadly.

A graph comparing the growth curves for logarithmic, linear, quasilinear, quadratic and exponential growth. Logarithmic is the shallowest curve, growing very slowly, and exponential is the fastest.

Summary

  • There are lots of books about standard data structures such as lists, trees and hash tables, and the algorithms for sorting and searching them. And there are lots of implementations of them already in class libraries. In this book we’ll look at the less well-known, more off-the-beaten-path data structures and algorithms that I had to learn about during my career. I’ve chosen the topics I found the most fabulous: the ones that are counterintuitive, or seemingly magical, or that push boundaries of languages.
  • I had to learn about almost all the topics in this book when I needed a new tool in my toolbox to solve a job-related problem. I hope this book saves you from having to read all the abstruse papers that I had to digest if you too have such a problem to solve.
  • But more important to me is that all these fabulous adventures gave me a deeper appreciation for what computer programmers are capable of. They changed how I think about the craft of programming. And I had a lot of fun along the way! I hope you do too.
  • Asymptotic complexity gives a measurement of how a solution scales to the size of the problem you’re throwing at it. We generally want algorithms to be better than quadratic if we want them to scale to large problems.
  • Complexity analysis can be subtle. It’s important to remember that time is not the only resource users care about, and that they might also have opinions on whether avoiding a bad worst-case scenario is more or less important than achieving an excellent average performance.
  • If problems are always small, then asymptotic complexity matters less.
  • Reversing a linked list is straightforward if you have an immutable list! We’ll look at other kinds of immutable lists next.

FAQ

What makes an algorithm or data structure “fabulous” in this book’s sense?They solve real problems off the beaten path, produce counterintuitive wins (like using immutability for undo/redo), apply across domains (e.g., backtracking from trees to pretty printers), emphasize meaning over mechanisms, feel like “magic tricks” (Hughes list), exploit language features deeply (e.g., C# generics), reframe problems for big gains (HashLife), connect to theory (category patterns), and keep programming fun.
What’s the difference between a data structure and an algorithm?A data structure organizes information; an algorithm is a finite set of steps to solve a problem. Algorithms can be nondeterministic (use randomness), need not run on computers, and can be conceptually simple even when they do lots of work.
What is algorithmic complexity and how does Big-O describe it?Complexity relates problem size to cost (time, memory, or other resources). Big-O gives growth rates: O(1), O(log n), O(n), O(n log n), O(n²), O(2ⁿ)/O(n!). It abstracts constants and focuses on how cost scales as input grows.
How should I choose the “size” of a problem when analyzing complexity?Use the quantity that best matches the work the algorithm does and state it explicitly when non-obvious. For collections it’s often the number of elements; for trees it might be height rather than node count.
Why aren’t asymptotically faster algorithms always the best choice?Because real workloads have typical inputs and constant factors matter. A naive O(n²) string search can outperform linear-time methods on short strings and simple patterns—what most users actually do.
How is the chapter’s immutable linked list structured?Each node holds a Value and a Tail (the rest of the list). There is a singleton Empty list. Push prepends a value, producing a new list; existing lists never change. Empty is a real object you can call methods on.
What performance pitfalls exist in the initial list implementation?- IsEmpty used record equality, making it costlier than necessary; Tail == null is a cheaper check for emptiness. - Auto-generated record equality compares values recursively, so list equality is O(k) in the shared prefix and risks stack overflow on very long equal prefixes. - ToString used repeated string concatenation, causing accidental O(n²) time and memory.
Why is the naive ToString accidentally quadratic, and how do you fix it?Each append copies the accumulated string, so total work grows with the sum of 1..n. Use a StringBuilder (or equivalent) to accumulate in O(n) time and memory.
How do you reverse an immutable linked list, and what does it cost?Iterate the original list, pushing each value onto a new list. The original remains unchanged; the result is reversed. This runs in O(n) time and uses O(n) additional memory.
What topics come next after this chapter?Twists on classic structures (stacks, queues, trees), persistence and memoization for time/space wins, elegant list-reordering tricks, backtracking for graph coloring and pretty printing, unification/anti-unification, probabilistic programming tools and Bayesian inference, and brief theory interludes linking category-theoretic patterns to everyday types—all in C# but broadly applicable.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$399.99
only $33.33 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Fabulous Adventures in Data Structures and Algorithms ebook for free
choose your plan

team

monthly
annual
$49.99
$399.99
only $33.33 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Fabulous Adventures in Data Structures and Algorithms ebook for free