Proszę oceńcie co mogę zmienić, co dodać. Od siebie na pewno chcę ogarnąć unit testy w cmocku żeby nauczyć się pisać kod zgodnie z TDD. Co do kodu to jest i ma być C, nie żaden C++.
main.c
#include <stdio.h>
#include "linked_list.h"
int main(void) {
printf("** testing push_back, push_front, pop_back, pop_front operations **\n\n");
struct ll_node *node = ll_new(2);
if (!node) {
fprintf(stderr, "failed to alocate memory for linked list");
return 1;
}
ll_push_back(&node, 3);
ll_push_back(&node, 4);
ll_push_front(&node, 1);
ll_print(node);
// int result;
// ll_pop_front(&node, &result);
// printf("first call ll_pop_front: %d\n", result);
// ll_pop_front(&node, &result);
// printf("second call ll_pop_front: %d\n", result);
// ll_pop_back(&node, &result);
// printf("first call ll_pop_back: %d\n", result);
// ll_pop_back(&node, &result);
// printf("second call ll_pop_back: %d\n", result); <- tu wywala się program
if (ll_is_empty(node)) {
printf("list is empty");
}
ll_destroy(node);
return 0;
}
linked_list.h
#ifndef LINKED_LIST_H
#define LINKED_LIST_H
#include <stdbool.h>
struct ll_node {
int data;
struct ll_node *prev;
struct ll_node *next;
struct ll_node *head;
struct ll_node *tail;
};
struct ll_node *ll_new(int data);
int ll_destroy(struct ll_node *node);
int ll_push_back(struct ll_node **node, int data);
int ll_push_front(struct ll_node **node, int data);
int ll_pop_back(struct ll_node **node, int *data);
int ll_pop_front(struct ll_node **node, int *data);
int ll_delete_at(struct ll_node **node, int index, int *data);
bool ll_contains(struct ll_node *node, int data);
int ll_find(struct ll_node *node, int data);
int ll_size(struct ll_node *node);
bool ll_is_empty(struct ll_node *node);
bool ll_is_index_valid(struct ll_node *node, int index);
struct ll_node *ll_get_node_at(struct ll_node *node, int index);
int ll_get(struct ll_node *node, int index, int *data);
int ll_set(struct ll_node **node, int index, int data);
int ll_print(struct ll_node *node);
#endif //LINKED_LIST_H
linked_list.c
#include "linked_list.h"
#include <stdio.h>
#include <stdlib.h>
struct ll_node *ll_new(int data) {
struct ll_node* node = malloc(sizeof(*node));
if (!node) {
return NULL;
}
node->data = data;
node->prev = NULL;
node->next = NULL;
return node;
}
int ll_destroy(struct ll_node *node) {
if (!node) {
return -1;
}
while (node->next != NULL) {
struct ll_node *current = node;
node = node->next;
free(current);
}
return 0;
}
int ll_push_back(struct ll_node **node, int data) {
if (!node) {
return -1;
}
struct ll_node *tail = *node;
while (tail->next != NULL) {
tail = tail->next;
}
struct ll_node *current = ll_new(data);
current->next = NULL;
current->prev = *node;
tail->next = current;
return 0;
}
int ll_push_front(struct ll_node **node, int data) {
if (!node) {
return -1;
}
struct ll_node *head = ll_new(data);
head->next = *node;
head->prev = NULL;
*node = head;
return 0;
}
int ll_pop_back(struct ll_node **node, int *data) {
if (!node) {
return -1;
}
struct ll_node *current = *node;
while (current->next != NULL) {
current = current->next;
}
int old_data = current->data;
free(current);
if (data) {
*data = old_data;
}
return 0;
}
int ll_pop_front(struct ll_node **node, int *data) {
if (!node) {
return -1;
}
int old_data = (*node)->data;
*node = (*node)->next;
if (*node) {
free((*node)->prev);
}
(*node)->prev = NULL;
if (data) {
*data = old_data;
}
return 0;
}
int ll_delete_at(struct ll_node **node, int index, int *data) {
struct ll_node *current = ll_get_node_at(*node, index);
if (!current) {
return -1;
}
if (data) {
*data = current->data;
}
current->prev->next = current->next;
current->next->prev = current->prev;
free(current);
return 0;
}
bool ll_contains(struct ll_node *node, int data) {
while (node->next != NULL) {
if (node->data != data) {
return false;
}
node = node->next;
}
return true;
}
int ll_find(struct ll_node *node, int data) {
if (!node) {
return -1;
}
int idx = 0;
while (node->next != NULL) {
if (node->data == data) {
return idx;
}
++idx;
node = node->next;
}
return -1;
}
int ll_size(struct ll_node *node) {
if (!node) {
return -1;
}
int size = 0;
while (node != NULL) {
++size;
node = node->next;
}
return size;
}
bool ll_is_empty(struct ll_node *node) {
return ll_size(node) == 0;
}
bool ll_is_index_valid(struct ll_node *node, int idx) {
return node && !(idx < 0 || idx >= ll_size(node));
}
struct ll_node *ll_get_node_at(struct ll_node *node, int index) {
if (!ll_is_index_valid(node, index) || !node) {
return NULL;
}
int n = 0;
while (node->next != NULL) {
if (n++ == index) {
break;
}
node = node->next;
}
return node;
}
int ll_get(struct ll_node *node, int index, int *data) {
struct ll_node *result = ll_get_node_at(node, index);
if (!result) {
return -1;
}
*data = result->data;
return 0;
}
int ll_set(struct ll_node **node, int index, int data) {
struct ll_node *current = ll_get_node_at(*node, index);
if (!current) {
return -1;
}
current->data = data;
return 0;
}
int ll_print(struct ll_node *node) {
if (!node) {
return -1;
}
int i = 0;
while (node != NULL) {
printf("node %d: data=%d\n", i, node->data);
node = node->next;
++i;
}
return 0;
}