5

At the moment I am working on creating a small library for common data structures in C. This is mainly for learning purposes, but I do plan to use this library in other projects to see how well it works and where the problems are. So far I'm content with my hash and binary tree implementation, but I cannot decide on the design of the linked list.

All the data structures implemented so far work with void pointers and take no responsibility for creating or destroying data, i.e. they only reference the data. One design goal is to keep them as generic as possible to increase the reuseability.

Regarding the linked list, I've found three approaches so far:

  1. Dedicated list head: the list features a dedicated list head which is used as an abstract data type.

  2. Nodes only: like the example above, except that all functions operate on a list_node. Used in GLib.

  3. In payload: add a list_node structure to the payload data and calculate the offset to the payload with a macro. See lists in the linux kernel

  4. EDIT Generate typed lists with macros: use macros to create type-specific versions of the list structures and functions.

    Example for 1 and 2:


/* list.h */
typedef struct list_t list;

typedef int (*comparator)(const void* a, const void* b);

list* list_new          (comparator c);
void  list_delete       (list* l);
void  list_insert_after (list* l, uint32_t index, void* data);
void  list_remove       (list* l, void* data);
uint32_t list_size      (list* l);
/* other functions operating on lists */

/* list.c */
#include "list.h"

typedef struct list_node_t {
  struct list_node_t* next;
  struct list_node_t* prev;
  void* data;
} list_node;

struct list_t {
  list_node* begin;
  list_node* end;
  uint32_t   size;
  comparator cmp;
}


Now to the question: which of these approaches is the most versatile? Are there any other approaches?

21
  • 2
    It's probably better to use size_t for index, size, etc, rather than uint32_t. Commented Jun 22, 2011 at 8:32
  • you've got comparators in there, are you trying to implement a priority queue? A basic linked list doesn't need comparators and heaps are a better structure for handling pqueues Commented Jun 22, 2011 at 8:33
  • You might want to take a look at sys/queue.h for implementations too. Commented Jun 22, 2011 at 8:36
  • @tobyodavies the comparator is needed for list_remove and list_insert_after in the example above, because those two functions would find the element in question by comparing it to whatever is there where the data pointer points to. Commented Jun 22, 2011 at 8:50
  • 1
    @Dario - Perhaps those two functions should take a comparator argument, rather than making it an inherent part of the list. Commented Jun 22, 2011 at 9:13

2 Answers 2

1

I prefer the second approach, i.e. nodes only.

It has the advantage of being extremely simple, since the results of most list operations (split, push, pop, sublist, ...) are themselves lists.

Also note that you're lacking important list operations, mainly push() and pop(). You should make use of the fact that lists allow insertion in O(1).

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the advice! The interface given in the example is by no means complete, it is just supposed to illustrate the point.
I'd actually prefer a mix of 1 and 2 - 2 for when nodes are enough, but 1 for situations when the extra info that can be stored in a lis head (i.e. end, size, etc.) can cause significant speedups.
0

Note that you don't necessarily have to use void * pointers. You can use macro pasting tricks to generate types/function(by appending type name to types and functions) for generic type safe data structures.

ex.: http://sglib.sourceforge.net/

1 Comment

Certainly an interesting approach, do you know of any projects that use sglib?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.