init commit
This commit is contained in:
commit
9904bd2212
16 changed files with 846 additions and 0 deletions
19
llist/Makefile
Normal file
19
llist/Makefile
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
CC=gcc
|
||||
CFLAGS=-Wall -Wextra
|
||||
|
||||
OBJS=test.o llist.o
|
||||
|
||||
all: test
|
||||
|
||||
test: $(OBJS)
|
||||
gcc -o $@ $^
|
||||
|
||||
test.o: test.c
|
||||
|
||||
llist.o: llist.c llist.h
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS)
|
||||
rm -f test
|
||||
|
||||
.PHONY: all, clean
|
||||
174
llist/llist.c
Normal file
174
llist/llist.c
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/**
|
||||
* llist.c - a basic linked list implementation.
|
||||
*
|
||||
* Used for the hashtable.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "llist.h"
|
||||
|
||||
/**
|
||||
* Node in the linked list
|
||||
*/
|
||||
typedef struct LLNodeT
|
||||
{
|
||||
void* data;
|
||||
struct LLNodeT* next;
|
||||
}
|
||||
LLNode;
|
||||
|
||||
/**
|
||||
* Create a new linked list
|
||||
*/
|
||||
LL* ll_create(void)
|
||||
{
|
||||
LL* ll = malloc(sizeof(LL));
|
||||
ll->entries = 0;
|
||||
return ll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add item to beginning of a linked list
|
||||
*/
|
||||
int ll_push(LL* ll, void* data)
|
||||
{
|
||||
LLNode* n = malloc(sizeof(*n));
|
||||
|
||||
n->data = data;
|
||||
|
||||
// Reassign the head
|
||||
n->next = ll->head;
|
||||
ll->head = n;
|
||||
|
||||
ll->entries++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add item to end of a linked list
|
||||
*/
|
||||
int ll_append(LL* ll, void* data)
|
||||
{
|
||||
LLNode* tail = ll->head;
|
||||
|
||||
// Just push if there are no nodes yet
|
||||
if (tail == NULL)
|
||||
{
|
||||
return ll_push(ll, data);
|
||||
}
|
||||
|
||||
// Travserse list to find tail
|
||||
while (tail->next != NULL)
|
||||
{
|
||||
tail = tail->next;
|
||||
}
|
||||
|
||||
// Create new node and assign it as tail
|
||||
LLNode* n = malloc(sizeof(LLNode));
|
||||
n->data = data;
|
||||
tail->next = n;
|
||||
|
||||
ll->entries++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item from the list via cb function
|
||||
*/
|
||||
void* ll_search(LL* ll, LLCb cb, void* arg)
|
||||
{
|
||||
LLNode* n = ll->head;
|
||||
|
||||
// Keep going until tail is reached
|
||||
while (n != NULL)
|
||||
{
|
||||
if (cb(n->data, arg) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
n = n->next;
|
||||
}
|
||||
|
||||
if (n == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return n->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and delete an entry from a linked list
|
||||
*/
|
||||
void* ll_delete(LL* ll, LLCb cb, void* arg)
|
||||
{
|
||||
LLNode* n = ll->head, *prev = NULL;
|
||||
|
||||
while (n != NULL)
|
||||
{
|
||||
if (cb(n->data, arg) == 0)
|
||||
{
|
||||
void* data = n->data;
|
||||
|
||||
// We are at the head
|
||||
if (prev == NULL)
|
||||
{
|
||||
ll->head = n->next;
|
||||
free(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
prev->next = n->next;
|
||||
free(n);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
prev = n;
|
||||
n = n->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a function to every node in a linked list
|
||||
*/
|
||||
int ll_loop(LL* ll, LLCb cb, void* arg)
|
||||
{
|
||||
LLNode* n = ll->head, *next;
|
||||
|
||||
while (n != NULL)
|
||||
{
|
||||
next = n->next;
|
||||
cb(n->data, arg);
|
||||
n = next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a linked list
|
||||
*/
|
||||
void ll_free(LL* ll)
|
||||
{
|
||||
LLNode* n = ll->head, *next;
|
||||
|
||||
while (n != NULL)
|
||||
{
|
||||
next = n->next;
|
||||
free(n);
|
||||
n = next;
|
||||
}
|
||||
|
||||
free(ll);
|
||||
}
|
||||
|
||||
27
llist/llist.h
Normal file
27
llist/llist.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef _LLIST_H_
|
||||
#define _LLIST_H_
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct LLNodeT* head;
|
||||
int entries;
|
||||
}
|
||||
LL;
|
||||
|
||||
typedef int (*LLCb)(void*, void*);
|
||||
|
||||
LL* ll_create(void);
|
||||
|
||||
int ll_push(LL* ll, void* data);
|
||||
|
||||
int ll_append(LL* ll, void* data);
|
||||
|
||||
void* ll_search(LL* ll, LLCb cb, void* arg);
|
||||
|
||||
void* ll_delete(LL* ll, LLCb cb, void* arg);
|
||||
|
||||
int ll_loop(LL* ll, LLCb cb, void* arg);
|
||||
|
||||
void ll_free(LL* ll);
|
||||
|
||||
#endif
|
||||
83
llist/test.c
Normal file
83
llist/test.c
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "llist.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* name;
|
||||
char* team;
|
||||
int age;
|
||||
}
|
||||
Player;
|
||||
|
||||
Player* create_player(char* name, char* team, int age)
|
||||
{
|
||||
Player* p = malloc(sizeof(*p));
|
||||
p->team = strdup(team);
|
||||
p->name = strdup(name);
|
||||
p->age = age;
|
||||
return p;
|
||||
}
|
||||
|
||||
int find_player(void* data, void* arg)
|
||||
{
|
||||
Player* player = data;
|
||||
return strcmp(player->name, (char*) arg);
|
||||
}
|
||||
|
||||
int change_team(void* data, void* arg)
|
||||
{
|
||||
Player* player = data;
|
||||
player->team = (char*) arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("Creating new linked list...");
|
||||
|
||||
LL* ll = ll_create();
|
||||
|
||||
puts("Pushing some data...");
|
||||
|
||||
Player* lebron = create_player("Lebron James", "Lakers", 37);
|
||||
Player* giannis = create_player("Giannis Antetokounmpo", "Bucks", 27);
|
||||
|
||||
ll_push(ll, lebron);
|
||||
ll_push(ll, giannis);
|
||||
|
||||
puts("Finding the data that was pushed...");
|
||||
|
||||
assert(ll_search(ll, find_player, "Lebron James") == lebron);
|
||||
|
||||
puts("Appending some data...");
|
||||
|
||||
Player* kd = create_player("Kevin Durant", "Nets", 33);
|
||||
|
||||
ll_append(ll, kd);
|
||||
|
||||
puts("Finding the data that was appended...");
|
||||
|
||||
assert(ll_search(ll, find_player, "Kevin Durant") == kd);
|
||||
|
||||
puts("Looping over linked list and applying change...");
|
||||
|
||||
ll_loop(ll, change_team, "Bucks");
|
||||
|
||||
Player* kd_ref = ll_search(ll, find_player, "Kevin Durant");
|
||||
|
||||
assert(strcmp(kd_ref->team, "Bucks") == 0);
|
||||
|
||||
puts("Deleting data from linked list...");
|
||||
|
||||
ll_delete(ll, find_player, "Lebron James");
|
||||
|
||||
assert(ll_search(ll, find_player, "Lebron James") == NULL);
|
||||
|
||||
puts("Tests complete!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue