Skip to content
Snippets Groups Projects
Commit 7fa3e5e6 authored by Mactavish's avatar Mactavish
Browse files

add solution to linked-list

parent 30b520a5
No related branches found
No related tags found
No related merge requests found
#include "linked_list.h"
#include <errno.h>
#include <stdlib.h>
#define FAULT(ERRNO, ERR_CODE) \
errno = ERRNO; \
exit(ERR_CODE);
#define FREE_NODE(NODE) \
if (NODE) { \
free(NODE); \
NODE = NULL; \
}
struct list_node {
struct list_node *prev, *next;
ll_data_t data;
struct list_node *prev, *next;
ll_data_t data;
};
struct list {
struct list_node *first, *last;
struct list_node *first, *last;
};
struct list_node *create_node(ll_data_t data) {
// TODO: implement create_node
struct list_node *node;
node = malloc(sizeof(struct list_node));
if (!node) {
FAULT(ENOMEM, EXIT_FAILURE);
}
node->data = data;
return node;
}
// constructs a new (empty) list
struct list *list_create(void) {
// TODO: implement list_create
struct list *head = malloc(sizeof(struct list));
// create a dummy node, dummy node should not have any previous node
struct list_node *node = create_node(0);
head->first = node;
head->last = node;
node->prev = node->next = NULL;
return head;
}
// counts the items on a list
size_t list_count(const struct list *list) {
// TODO: implement list_count
size_t count = 0;
if (list->first == list->last) {
return count;
}
struct list_node *dummy = list->first;
struct list_node *node = dummy->next;
while (node != dummy) {
node = node->next;
count++;
}
return count;
}
// inserts item at back of a list
void list_push(struct list *list, ll_data_t item_data) {
// TODO: implement list_push
struct list_node *node = create_node(item_data);
// empty list with a dummy node
if (list->first == list->last) {
list->first->next = node;
list->last = node;
node->prev = node->next = list->first;
} else {
node->prev = list->last;
list->last->next = node;
node->next = list->first;
list->last = node;
}
}
// removes item from back of a list
ll_data_t list_pop(struct list *list) {
// TODO: implement list_pop
// empty list with a dummy node
if (list->first == list->last) {
FAULT(EFAULT, EXIT_FAILURE);
}
struct list_node *last = list->last;
ll_data_t data = last->data;
list->last = last->prev;
last->prev->next = list->first;
FREE_NODE(last);
return data;
}
// inserts item at front of a list
void list_unshift(struct list *list, ll_data_t item_data) {
// TODO: implement list_unshift
// empty list with a dummy node
if (list->first == list->last) {
list_push(list, item_data);
} else {
struct list_node *dummy = list->first, *node = create_node(item_data);
node->next = dummy->next;
node->prev = dummy;
dummy->next->prev = node;
dummy->next = node;
}
}
// removes item from front of a list
ll_data_t list_shift(struct list *list) {
// TODO: implement list_shift
// empty list with a dummy node
if (list->first == list->last) {
FAULT(EFAULT, EXIT_FAILURE);
} else {
struct list_node *dummy = list->first, *node;
node = dummy->next;
ll_data_t data = node->data;
dummy->next = node->next;
// if there are more than one nodes
if (node->next->prev == node) {
node->next->prev = dummy;
} else {
list->last = list->first;
}
FREE_NODE(node);
return data;
}
}
// deletes a node that holds the matching data
void list_delete(struct list *list, ll_data_t data) {
// TODO: implement list_delete
if (list->first == list->last) {
errno = EFAULT;
exit(EXIT_FAILURE);
} else {
struct list_node *dummy = list->first;
struct list_node *node = dummy->next;
while (node != dummy) {
if (node->data == data) {
break;
}
node = node->next;
}
if (node != dummy) {
node->prev->next = node->next;
node->next->prev = node->prev;
if (node == list->last) {
list->last = node->prev;
}
FREE_NODE(node);
}
}
}
// destroys an entire list
// list will be a dangling pointer after calling this method on it
void list_destroy(struct list *list) {
// TODO: implement list_destroy
// empty list with a dummy node
if (list->first == list->last) {
FREE_NODE(list->last);
FREE_NODE(list);
} else {
struct list_node *dummy = list->first;
struct list_node *node = dummy->next, *next;
while (node != dummy) {
next = node->next;
FREE_NODE(node);
node = next;
}
FREE_NODE(dummy);
FREE_NODE(list);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment