Last active
March 20, 2020 18:20
-
-
Save pedrominicz/4f00d5ed0a7180b51e94824998e1e319 to your computer and use it in GitHub Desktop.
Linked list.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <stdbool.h> | |
#include <stddef.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
struct node { | |
int elem; | |
struct node* next; | |
}; | |
void node_push(struct node** node, int elem) { | |
assert(node); | |
if(*node) { | |
struct node* new_node = malloc(sizeof(struct node)); | |
new_node->elem = elem; | |
new_node->next = *node; | |
*node = new_node; | |
} else { | |
*node = malloc(sizeof(struct node)); | |
(*node)->elem = elem; | |
(*node)->next = NULL; | |
} | |
} | |
struct list { | |
struct node* head; | |
}; | |
struct list list_new(void) { | |
struct list list; | |
list.head = NULL; | |
return list; | |
} | |
void list_drop(struct list* list) { | |
assert(list); | |
struct node* node = list->head; | |
while(node) { | |
struct node* next = node->next; | |
free(node); | |
node = next; | |
} | |
list->head = NULL; | |
} | |
void list_push(struct list* list, int elem) { | |
assert(list); | |
node_push(&list->head, elem); | |
} | |
// All functions receive pointers to keep the interface consistent. | |
bool list_empty(struct list* list) { | |
assert(list); | |
return !list->head; | |
} | |
// Unsafe: may segfault if list is empty. | |
int list_pop(struct list* list) { | |
assert(list); | |
int elem = list->head->elem; | |
struct node* node = list->head; | |
list->head = list->head->next; | |
free(node); | |
return elem; | |
} | |
// Unsafe: may segfault if list is empty. | |
int list_peek(struct list* list) { | |
assert(list); | |
return list->head->elem; | |
} | |
void list_append(struct list* list, int elem) { | |
assert(list); | |
if(list->head) { | |
struct node* node = list->head; | |
while(node->next) { | |
node = node->next; | |
} | |
node->next = malloc(sizeof(node)); | |
node->next->elem = elem; | |
node->next->next = NULL; | |
} else { | |
struct node* node = malloc(sizeof(node)); | |
node->elem = elem; | |
node->next = NULL; | |
list->head = node; | |
} | |
} | |
void list_show(struct list* list) { | |
assert(list); | |
if(list->head) { | |
struct node* node = list->head; | |
while(node) { | |
printf("%d ", node->elem); | |
node = node->next; | |
} | |
} | |
printf("\n"); | |
} | |
int main(void) { | |
{ | |
struct list list = list_new(); | |
assert(list_empty(&list) == true); | |
list_append(&list, 3); | |
list_append(&list, 2); | |
list_append(&list, 1); | |
list_show(&list); | |
assert(list_empty(&list) == false); | |
list_push(&list, 2); | |
list_push(&list, 1); | |
list_show(&list); | |
assert(list_pop(&list) == 1); | |
assert(list_pop(&list) == 2); | |
list_show(&list); | |
assert(list_peek(&list) == 3); | |
list_drop(&list); | |
} | |
{ | |
struct list list = list_new(); | |
list_push(&list, 3); | |
list_push(&list, 2); | |
list_push(&list, 1); | |
list_show(&list); | |
list_drop(&list); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment