87 lines
1.8 KiB
C
87 lines
1.8 KiB
C
|
//
|
||
|
// Created by william on 1/16/24.
|
||
|
//
|
||
|
|
||
|
#include <stddef.h>
|
||
|
#include <malloc.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <assert.h>
|
||
|
#include "linked_list.h"
|
||
|
|
||
|
LinkedList linked_list_create(bool circular) {
|
||
|
LinkedList list;
|
||
|
|
||
|
list.circular = circular;
|
||
|
list.size = 0;
|
||
|
list.head = NULL;
|
||
|
list.end = NULL;
|
||
|
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
void linked_list_add(LinkedList *list, void *data) {
|
||
|
assert(list != NULL);
|
||
|
assert(data != NULL);
|
||
|
|
||
|
LinkedListNode *node = malloc(sizeof(LinkedListNode));
|
||
|
if (node == NULL) {
|
||
|
perror("Failed to allocate memory for linked list node");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
node->data = data;
|
||
|
node->previous = list->end;
|
||
|
|
||
|
if (list->head == NULL) {
|
||
|
list->head = node;
|
||
|
}
|
||
|
|
||
|
if (list->end != NULL) {
|
||
|
list->end->next = node;
|
||
|
}
|
||
|
|
||
|
if (list->circular) {
|
||
|
node->next = list->head;
|
||
|
} else {
|
||
|
node->next = NULL;
|
||
|
}
|
||
|
|
||
|
list->end = node;
|
||
|
list->size++;
|
||
|
}
|
||
|
|
||
|
void linked_list_destroy(LinkedList *list) {
|
||
|
assert(list != NULL);
|
||
|
|
||
|
LinkedListNode *node = list->head;
|
||
|
while (node != NULL) {
|
||
|
LinkedListNode *current_node = node;
|
||
|
node = node->next;
|
||
|
|
||
|
free(current_node);
|
||
|
|
||
|
if (node == list->head) {
|
||
|
// The list may be circular, we don't want an infinite free loop
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LinkedListCursor linked_list_cursor_create(LinkedList *list) {
|
||
|
LinkedListCursor cursor = {list->head};
|
||
|
return cursor;
|
||
|
}
|
||
|
|
||
|
LinkedListNode *linked_list_cursor_next(LinkedListCursor *cursor) {
|
||
|
if (cursor->current == NULL) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
LinkedListNode *next_node = cursor->current->next;
|
||
|
cursor->current = next_node;
|
||
|
return next_node;
|
||
|
}
|
||
|
|
||
|
bool linked_list_cursor_has_next(LinkedListCursor *cursor) {
|
||
|
return cursor->current != NULL && cursor->current->next != NULL;
|
||
|
}
|