https://github.com/attractivechaos/dlist
Five implementations of double linked lists to demonstrate generic data structures in C
https://github.com/attractivechaos/dlist
c double-linked-list generic-programming
Last synced: 9 months ago
JSON representation
Five implementations of double linked lists to demonstrate generic data structures in C
- Host: GitHub
- URL: https://github.com/attractivechaos/dlist
- Owner: attractivechaos
- Created: 2019-12-19T06:09:36.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2019-12-19T15:47:39.000Z (about 6 years ago)
- Last Synced: 2025-04-05T12:02:10.564Z (10 months ago)
- Topics: c, double-linked-list, generic-programming
- Language: C
- Homepage:
- Size: 13.7 KB
- Stars: 15
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## Generic Data Structures in C
Unlike C++, the C programming language doesn't provide a general mechanism to
implement generic data structures or algorithms. However, it is still possible
to write generic C code matching the performance of type-specific
implemntations. This repo demonstrates five ways to implement a generic
double-linked list in C. Some of these techniques can be adapted to other data
structures with no compromise on performance.
1. With `void*` pointers (`*-void.*`). This is the most common but often the
least efficient way to implement generic data structures. It requires extra
malloc per element, which wastes memory and hurts data locality. I don't recommend
it.
2. With intrusive data structures (`*-intru2.*`). This approach doesn't call
malloc/etc inside the library code, which gives callers full control of
memory management. It is the preferred way to implement double-linked
list, but is not optimal for binary trees because it incurs overhead to
comparisons between objects. Generally, intrusive data structures are not
applicable to vectors or [closed hash tables][closed-hash].
3. Combining intrusive data structures and macros (`*-intru1.*`). This is my
preferred way to implement binary trees (see [kavl.h][kavl]), but for
double-linked list, it is more complex.
4. With macros (`*-macro1.*`). This approach can be optimal for all common data
structures. However, it involves unusual syntax and is inflexible in terms of
memory management at the caller end. My [khash.h][khash] library is
implemented this way. STL containers also follow a similar rationale.
5. With before-header macros (`*-macro2.*`). This is an alternative way to
implement method 4 and is functionally equivalent. It gets rid of long
multi-line macros but complicates header inclusion.
I recommend method 2 for double-linked lists, 3 for binary search trees such as
red-black or AVL trees, and method 4 for plain vectors and closed hash tables.
[closed-hash]: https://en.wikipedia.org/wiki/Open_addressing
[khash]: https://github.com/attractivechaos/klib/blob/master/khash.h
[kavl]: https://github.com/attractivechaos/klib/blob/master/kavl.h