init commit

This commit is contained in:
Andrew Gundersen 2022-05-02 08:00:44 -05:00
commit 9904bd2212
16 changed files with 846 additions and 0 deletions

19
llist/Makefile Normal file
View 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
View 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
View 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
View 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;
}