#include <stdlib.h>
/*
* TODO: A lot of code missing here. You will need to add implementations for
* all the functions described in list.h here.
*
* Start by adding the definitions for the list and node structs. You may
* implement any of the Linked List versions discussed in the lecture, which
* have some different trade-offs for the functions you will need to write.
*
* Note: The function prototypes in list.h assume the most basic Singly Linked
* List. If you build some other version, you may not need all of the function
* arguments for all of the described functions. This will produce a warning,
* which you can suppress by adding a simple if-statement to check the value
* of the unused parameter.
*
* Also, do not forget to add any required includes at the top of your file.
*/
/* Linked list data structure. */
struct list {
struct node* head;
};
/* List node structure. */
struct node {
int data;
struct node* next;
};
/* Creates a new linked list and returns a pointer to it.
* Returns NULL on failure. */
struct list* list_init(void) {
struct list* l;
l = malloc(sizeof(struct list));
if (!l) {
return NULL;
}
else {
l -> head = NULL;
return l;
}
}
/* Creates a new node that contains the number num and returns a pointer to it.
* Returns NULL on failure. */
struct node* list_new_node(int num) {
struct node * n;
n = malloc(sizeof(struct node));
if (!n) {
return NULL;
}
else {
n -> data = num;
return n;
}
}
/* Returns the first node of the list L or NULL if list is empty. */
struct node* list_head(struct list* l) {
return l -> head;
}
/* Returns a pointer to the node after node N or NULL if N is the last node in
* the list. */
struct node* list_next(struct node* n) {
if (!n) {
return NULL;
}
else {
return n -> next;
}
}
/* Inserts node N at the front of list L.
* Returns 0 if N was succesfully inserted, 1 otherwise. */
int list_add_front(struct list* l, struct node* n) {
if (!l) {
return 1;
}
else {
if (l -> head == NULL) {
l -> head = n;
return 0;
}
else {
n -> next = l -> head;
l -> head = n;
}
return 0;
}
}
/* Returns the last node of the list L or NULL if list is empty. */
struct node* list_tail(struct list* l) {
struct node* currentnode = list_head(l);
struct node* nextnode = currentnode;
while (nextnode != NULL) {
currentnode = nextnode;
nextnode = list_next(currentnode);
}
return currentnode;
}
/* Returns a pointer to the node before node N in the list L, or returns NULL
* if N is the first node in the list or if N is not in the list at all. */
struct node* list_prev(struct list* l, struct node* n) {
struct node* currentnode = list_head(l);
if (currentnode == n) {
return NULL;
}
else {
struct node* previousnode = currentnode;
while (currentnode != n) {
previousnode = currentnode;
currentnode = list_next(previousnode);
}
return previousnode;
}
}
int list_add_back(struct list* l, struct node* n) {
if (!l || !n) {
return 1;
}
struct node* tail_node = list_tail(l);
tail_node -> next = n;
return 0;
}
int list_node_value(struct node* n) {
if (!n) {
return 0;
}
else {
return n -> data;
}
}
/* Unlink node N from list L. After unlinking, the list L contains no pointers
* to the node N and N contains no pointers to nodes in L.
* Returns 0 if N was succesfully unlinked from list L, or 1 otherwise */
int list_unlink_node(struct list* l, struct node* n) {
if (!l || !n) {
return 1;
}
// Link previous node with next_node;
struct node* prev_node = list_prev(l, n);
prev_node -> next = list_next(n);
n -> next = NULL;
return 0;
}
void list_free_node(struct node* n) {
if (n) {
free(n);
}
}
int list_cleanup(struct list* l) {
if (l == NULL) {
return 1;
}
struct node* currentnode = list_head(l);
struct node* nextnode = currentnode;
while (nextnode) {
currentnode = nextnode;
list_free_node(currentnode);
nextnode = list_next(nextnode);
}
free(l);
return 0;
}
int list_node_present(struct list* l, struct node* n) {
;
}
int list_insert_after(struct list* l, struct node* n, struct node* m) {
;
}
int list_insert_before(struct list* l, struct node* n, struct node* m) {
;
}
int list_length(struct list* l) {
;
}
struct node* list_get_ith(struct list* l, int i) {
;
}
struct list* list_cut_after(struct list* l, struct node* n) {
;
}
int main()
{
struct list* l = list_init();
struct node* nn = list_new_node(2);
printf("l address: %p \n", l);
printf("n address: %p \n", nn);
list_add_front(l, nn);
struct node* headnode = list_head(l);
struct node* nn2 = list_new_node(2);
printf("n2 address: %p \n", nn2);
list_add_front(l, nn2);
struct node* nn3 = list_new_node(12);
printf("n3 address: %p \n", nn3);
list_add_front(l, nn3);
struct node* nn0 = list_new_node(1);
printf("n0 address: %p \n", nn0);
list_add_back(l, nn0);
list_cleanup(l);
}