1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | #include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include "clog.h"
typedef struct _Node { // canonical type name is 'struct _Node'
int value;
struct _Node* next;
} Node; // shortcut (typedef) name is 'Node'
void print_list(Node* head) {
for(Node* curr = head; curr != NULL; curr = curr -> next) {
printf("[%d]", curr -> value);
printf(curr -> next != NULL ? "→" : "\n");
}
}
void append(int value, Node** a_head, Node** a_tail) {
// 1. Allocate memory for the new node.
Node* new_tail = malloc(sizeof(*new_tail));
// 2. Initialize the fields of the new node.
*new_tail = (Node) { .value = value, .next = NULL };
// 3. Depending on whether or not the list was initially empty…
if(*a_head == NULL) { // If list is empty (size 0)…
// … Set the head (*a_head) to the (address of) the new tail, or …
*a_head = new_tail; // type of *a_head is Node*. type of new_tail is Node*.
}
else {
// … Connect the old tail to the new tail.
(*a_tail) -> next = new_tail;
}
// 4. Set the tail (*a_tail) to the (address of the) new tail.
*a_tail = new_tail;
// IMPORTANT: This must come last.
}
void destroy_list(Node** a_head, Node** a_tail) {
while(*a_head != NULL) { // While list is not empty…
Node* new_head = (*a_head) -> next; // 1. Save (address of) new head (or NULL)
free(*a_head); // 2. Free the old head.
*a_head = new_head; // 3. Set the head to the new_head.
}
*a_tail = NULL; // 4. Set the tail to NULL.
// Order is important. If we free before saving the (address of) new_head, we won't
// be able to access it.
assert(*a_head == NULL);
}
int main(int argc, char* argv[]) {
Node* head = NULL; // Linked list of size 0 (empty list)
Node* tail = NULL;
append(10, &head, &tail);
assert(head == tail); // In a list of size 1, head and tail refer to the same Node.
append(11, &head, &tail);
assert(head != tail); // In a list of size 2, head and tail DON'T refer to the same Node
assert(tail -> value == 11);
append(12, &head, &tail);
print_list(head);
destroy_list(&head, &tail);
assert(head == NULL);
assert(tail == NULL);
return EXIT_SUCCESS;
}
/* vim: set tabstop=4 shiftwidth=4 fileencoding=utf-8 noexpandtab: */
|
© Copyright 2022 Alexander J. Quinn This content is protected and may not be shared, uploaded, or distributed.