I have been creating a DSA library in C for the last few months and here is my story.
It started as a learning journey. I refused to just know what a data structure is — I wanted to know how a data structure behaves internally, at the machine level. And that knowledge I couldn't get from any high-level language. So I chose C.
Not because it was trendy. In fact nobody really understands C except very few people. Because C doesn't lie to you, it doesn't give you ready-made data-structures like C++/Python/Java. If those high-level languages are coloring book for kids, C is a canvas with a bunch of colors and a brush, absolute freedom, but you are responsible for whatever you do. No compiler or garbage collector is coming to save you.
The problem with how we learn data structures -
Most DSA courses hand you an abstraction and call it understanding. Here's a linked list. It has nodes. Each node points to the next. Now go implement it in Python.
And you do. You make a class Node and use it's objects as individual nodes, and it works. And you move on thinking you understand it. But you have essentially just used a tool, never learnt how to make it, never understood what that tool is doing at the machine level. High level languages like Python and Java abstract it away from you. Those languages are good for productivity and getting things done as quickly as possible, but for understanding how computers work internally, I think there is no language better than C and I was so right.
The moment it got real: reversing a singly linked list in-place:-
I thought I understood linked lists. Then I tried to reverse one in-place — no extra memory, just pointer manipulation.
It took me days.
Not because the logic was complicated. Three pointers. prev, curr, next. Conceptually simple. But when you're doing it in C, with raw struct Node* pointers and no garbage collector watching your back, every wrong move is a segfault or worse — silent memory corruption that shows up three operations later with no explanation.
I had to slow down and think about what was actually happening in memory at each step. Not the diagram in my head. The actual bytes. The actual addresses. Where "curr->next" was pointing before I overwrote it, and whether I'd saved it in time.
When it finally worked, I understood pointer manipulation in a way no lecture had ever given me. Because I'd been forced to hold the machine state in my head.
The recursion thing nobody tells you:-
Tree traversals broke me and then rebuilt me.
I thought I had "understood" recursion before. I could write a factorial function. I could explain the call stack on a whiteboard. But inorder, preorder, postorder traversals on a tree I built myself exposed that I didn't really understand recursion at all.
I understood recursion as a concept. A function that calls itself. What I didn't understand was what the call stack was actually doing at each level, what state was preserved, when control returned and to where.
Building tree traversals in C - where the recursion is not just natural but inevitable because trees are essentially a manifestation of recursion, if recursion is a concept, trees give life to that abstract concept and bring it into existence. No textbook could have given me this understanding. But when I sat down with a pen and paper, traced the inorder traversals manually with a pen, it clicked with me and I could never forget what I learned for my whole life. This deep understanding cannot possibly be attained without pointers and manual memory management, making me proud of the decision that I chose C for learning Data structures.
The graph chapter humbled me:-
I thought I was getting good at this. Adjacency matrix representation was straightforward — a 2D array, clean indexing, done.
Then I moved to adjacency list representation.
Suddenly I'm managing an array of linked lists. It was way harder than I expected. Dynamic memory for each list. Pointer-to-pointer logic for insertions. Edge cases multiplying. The same graph concept, implemented differently, was an entirely different problem in terms of what the code had to actually do.
It was humbling. It reminded me that understanding a data structure conceptually and implementing it are two very different things. Representation matters. The choice of how you store something changes everything downstream. The impact was real and positive. While with adjacency matrix you have to traverse the entire 2D array even when most of it is empty, it gives a time complexity of O(V2) where V was the number of vertices, whereas in adjacency list the time complexity is O(V+E) where V is vertices and E is the edges in the graph. Because we are only traversing the vertices with an edge rather than skimming entire adjacency matrix like an idiot. Adjacency matrix also has it's place because they are simpler, but they are useful in dense graphs. In sparse graphs, they actually waste a lot of time as well as memory.
What I actually built:-
The result is an interactive, terminal-based DSA library in C - stacks, queues, linked lists, trees, graphs - dfs/bfs, expression evaluation, hashing algos, searching and sorting algos — all from scratch. Manual memory management throughout.
Infix to postfix and Postfix evaluation demo -
Binary search tree demo -
You can run it, interact with it, watch the operations happen, run Valgrind over it. Every line of code is something I wrote after understanding why it needed to exist and every single line has its place in my 4000+ line codebase and each line can be justified.
The project is on GitHub if you want to look at the code, break it, contribute or steal from it — all of that is fine by me.
Here is the link - https://github.com/darshan2456/C_DSA_interactive_suite
Most learning environments are optimised for speed - get to the answer, move to the next concept. That works. But it leaves gaps that are easy to not notice until they matter.
Building this library was my way of going back and filling those gaps. Not because someone asked me to, but because I couldn't comfortably move forward without it.If you've ever felt that same discomfort - that sense that you're using something you don't fully understand - that instinct is worth following.
C is one of the most honest places to follow it. And once you've worked in it, you'll notice its absence everywhere else.
Top comments (2)
This hits hard. The “you used a tool but never understood it” line is something most of us don’t realize until much later. The way you described reversing a linked list and recursion is exactly where theory breaks and real understanding begins. Respect for sticking through the uncomfortable part, that’s where actual engineering happens.
Also love that you didn’t just stop at learning but built a full interactive suite. That’s incredible.
Thanks a lot pal. Means a lot to me.