Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design of a linked list implementation in C

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?

like image 789
Dario Hamidi Avatar asked Nov 14 '22 21:11

Dario Hamidi


1 Answers

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).

like image 96
Philip Avatar answered Dec 30 '22 03:12

Philip