Created
February 16, 2014 17:23
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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