Skip to content

Instantly share code, notes, and snippets.

@reuk
Created February 16, 2014 17:23
Show Gist options
  • Save reuk/9037545 to your computer and use it in GitHub Desktop.
Save reuk/9037545 to your computer and use it in GitHub Desktop.
Super simple non-type-safe linked-list implementation in C, because I got bored.
//
// LinkedList.c
// LinkedList
//
// Created by Reuben Thomas on 16/02/2014.
// Copyright (c) 2014 Reuben Thomas. All rights reserved.
//
#include "LinkedList.h"
#include <stdlib.h>
struct _Link
{
void * data;
ListHandle next;
};
void * list_car (ListHandle head)
{
return head->data;
}
ListHandle list_cdr (ListHandle head)
{
return head->next;
}
ListHandle list_construct (void * first, ...)
{
va_list v;
void * arg = first;
ListHandle head, node;
head = malloc (sizeof (Link));
node = head;
node->data = first;
va_start (v, first);
while ((arg = va_arg (v, void *)))
{
node->next = malloc (sizeof (Link));
node = node->next;
node->data = arg;
}
node->next = 0;
return head;
}
void list_destruct_data (ListHandle head)
{
if (list_cdr (head))
{
list_destruct_data (list_cdr (head));
free (list_car (head));
}
}
void list_destruct (ListHandle head)
{
if (list_cdr (head))
{
list_destruct (list_cdr (head));
free (head);
}
}
ListHandle list_cons (void * head, ListHandle tail)
{
ListHandle handle = malloc (sizeof (Link));
Link link = {head, tail};
*handle = link;
return handle;
}
ListHandle list_back (ListHandle head)
{
if (list_cdr (head))
return list_back (list_cdr (head));
return head;
}
void list_append_m (ListHandle front, ListHandle back)
{
list_back (front)->next = back;
}
ListHandle list_copy (ListHandle head)
{
ListHandle handle = malloc (sizeof (Link));
Link link =
{ list_car (head)
, list_cdr (head) ? list_copy (list_cdr (head)) : 0
};
*handle = link;
return handle;
}
ListHandle list_append (ListHandle front, ListHandle back)
{
ListHandle handle = malloc (sizeof (Link));
Link link =
{ list_car (front)
, list_cdr (front) ? list_append (list_cdr (front), back) : list_copy (back)
};
*handle = link;
return handle;
}
//
// LinkedList.h
// LinkedList
//
// Created by Reuben Thomas on 16/02/2014.
// Copyright (c) 2014 Reuben Thomas. All rights reserved.
//
#ifndef LinkedList_LinkedList_h
#define LinkedList_LinkedList_h
#include <stdarg.h>
typedef struct _Link Link;
typedef Link * ListHandle;
void * list_car (ListHandle head);
ListHandle list_cdr (ListHandle head);
ListHandle list_construct (void * first, ...);
void list_destruct (ListHandle head);
void list_destruct_data (ListHandle head);
ListHandle list_cons (void * head, ListHandle tail);
void list_append_m (ListHandle front, ListHandle back);
ListHandle list_append (ListHandle front, ListHandle back);
#endif
//
// main.c
// LinkedList
//
// Created by Reuben Thomas on 16/02/2014.
// Copyright (c) 2014 Reuben Thomas. All rights reserved.
//
#include "LinkedList.h"
#include <stdio.h>
#include <stdlib.h>
void printIntList (ListHandle head)
{
printf ("%i\n", *(int *)list_car (head));
if (list_cdr (head))
printIntList (list_cdr (head));
}
int main(int argc, const char * argv[])
{
printf("Hello, World!\n");
const int NUM = 10;
int * nums = malloc (sizeof (int) * NUM);
for (int i = 0; i != NUM; ++i)
{
nums[i] = i;
}
ListHandle head0 = list_construct (nums + 0, nums + 2, nums + 4, nums + 6, nums + 8, NULL);
ListHandle head1 = list_construct (nums + 1, nums + 3, nums + 5, nums + 7, nums + 9, NULL);
printf ("\nlist 1\n");
printIntList (head0);
printf ("\nlist 2\n");
printIntList (head1);
printf ("\ncons test\n");
head0 = list_cons (nums + 1, head0);
printIntList(head0);
printf ("\nappend test\n");
ListHandle head2 = list_append (head0, head1);
printIntList (head2);
printf ("\nmutable append test\n");
list_append_m (head1, head0);
printIntList (head1);
// don't need to destruct head0 because its memory now belongs to head1
list_destruct (head1);
list_destruct (head2);
// more dynamic list construction
ListHandle dynamicList = list_cons (nums + 1,
list_cons (nums + 1,
list_cons (nums + 2,
list_cons (nums + 3,
list_cons (nums + 5,
list_cons (nums + 8,
NULL))))));
printf ("\ndynamic list\n");
printIntList (dynamicList);
list_destruct (dynamicList);
free (nums);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment