Week 9 Code Examples
// Jake's LL demo
// But now Henry Hickman is here!
// Add integers to a LL.
// Print the entire structure
#include <stdio.h>
#include <stdlib.h>
struct node {
// the data! Also called the payload.
int data;
// a pointer to the next node in the LL.
struct node *next;
};
// A function that creates a struct node, with some data that's passed in.
// Returns a pointer to the node on the heap.
// we do this to clean up main.
struct node *create_node(int data_to_add) {
// Allocate memory on the heap
// we'll use sizeof(struct node) to get the exact memory required
//printf("Allocating %lu bytes on the heap for a new node\n", sizeof(struct node)); // keep in mind struct packing might make the answer surprise you
struct node *new_node = malloc(sizeof(struct node));
// initialises the new node's fields
// The aarrow oeprator -> is equivalent to a derefence then a field access: (*new_node).data = data_to_add;
new_node->data = data_to_add;
new_node->next = NULL; // NULL is a memory address reserved, that can't be dereferenced. usually at 0x000000
// we return the address of this node on the heap
return new_node;
}
void print_linked_list(struct node *head) {
// we need a current node that iterates through the list
// starting from the head node, we don't actually want to move the 'head' pointer.
// we are creating a pointer to refer to where head was pointing to...
struct node *current = head;
printf("Linked list: ");
// we loop. We loop as long as the current node is NOT at the NULL pointer.
while (current != NULL) {
printf("%d->", current->data);
current = current->next;
}
printf("NULL\n");
}
//Free all nodes in the linked list
void free_all_nodes(struct node *head) {
struct node *current = head;
//Traverses the linked list until we're at the end
while (current != NULL) {
//Gets the current node in preperation of freeing it
struct node *node_to_free = current;
//Moves on with our life to the next node
current = current->next;
//Frees the node, so we don't have a memory leak
free(node_to_free);
}
printf("Freed all the nodes in the linked list\n");
}
//Insert at the beginning of a linked list
struct node *insert_at_head(struct node *head, struct node *new_node) {
struct node *prev_head = head;
//Our new node points to what use to be the start of the linked list
new_node->next = prev_head;
//The start of our linked list is now the new node
head = new_node;
return head;
}
//Inserts at the tail of a linked list
struct node *insert_at_tail(struct node *head, struct node *new_node) {
if (head == NULL) {
head = new_node;
return head;
}
struct node *current = head;
//So that we don't fall of the end of our linked list
//Stop when the next item is NULL
while (current->next != NULL) {
current = current->next;
}
//We are at the very last node in our list
//Make it point to our new node
current->next = new_node;
return head;
}
//Inserts in the middle of a linked list
struct node *insert_at_index(struct node *head, struct node *new_node, int index) {
//There's a few cases we haven't considered
//Let's go through them today
struct node *current = head;
int counter = 0;
if (index < 0) {
return head;
}
if (index == 0) {
new_node->next = head;
head = new_node;
return head;
}
//Will continue until we are one before where we want our node to end up
while (counter < index - 1 && current != NULL) {
current = current->next;
//Keeps track of what index we are at
counter++;
}
struct node *prev_next = current->next;
current->next = new_node;
new_node->next = prev_next;
return head;
}
//Deletes from a given index
struct node *delete_at_index(struct node *head, int index) {
//There's a few cases we haven't considered
//Let's go through them today
if (index == 0) {
struct node *prev_head = head;
head = head->next;
free(prev_head);
return head;
}
struct node *current = head;
int counter = 0;
//Counts up to where we want to go
while (counter < index - 1) {
//Proceeds to next
current = current->next;
counter++;
}
//Gets the node we want to delete
struct node *node_to_free = current->next;
//Gets the node we want to point at next
//Only if it exists
struct node *to_point_at;
if (node_to_free->next != NULL) {
to_point_at = node_to_free->next;
} else {
//Otherwise we will point to NULL
to_point_at = NULL;
}
current->next = to_point_at;
free(node_to_free);
return head;
}
//Inserts items in [ascending or descending] order
struct node *insert_in_order(struct node *head, struct node *new_node) {
//Checks if the head is NULL
if (head == NULL) {
head = new_node;
return head;
}
//Checks if the new_node is smaller than the head
if (new_node->data < head->data) {
new_node->next = head;
head = new_node;
return head;
}
struct node *current = head;
while (current->next != NULL) {
if (new_node->data < current->next->data) {
new_node->next = current->next;
current->next = new_node;
return head;
}
current = current->next;
}
current->next = new_node;
return head;
}
//Reverses a linked list
struct node *reverse_linked_list(struct node *head) {
struct node *current = head;
struct node *prev = NULL;
struct node *next = NULL;
//Keep going until current is NULL
while (current != NULL) {
//Storing current->next for later when we want to traverse down the list
next = current->next;
//Setting current->next to what came before it (NULL at the start)
current->next = prev;
//For future iterations, prev will be whatever node we were just at
prev = current;
//Use what we saved, and move down to the next node
current = next;
}
//Because the head is no longer the head, we need to return prev instead
return prev;
}
//Concatenates two linkned lists together
struct node *concatenate (struct node *head1, struct node *head2) {
//If head1 is NULL, head2 might be a linked list so we'll return it
if (head1 == NULL) {
return head2;
} else if (head2 == NULL) {
//If head2 is NULL, head1 might be a linked list, so we'll return it
return head1;
}
struct node *current = head1;
//Traverse the linked list as normal, until we get to the last node
while (current->next != NULL) {
current = current->next;
}
//Adding head2 to the end of the first linked list
current->next = head2;
return head1;
}
//Counts how many nodes are divisible by six
int div_6(struct node *head) {
if (head == NULL) {
return 0;
}
struct node *current = head;
int counter = 0;
while (current != NULL) {
if (current->data % 6 == 0) {
counter++;
}
current = current->next;
}
return counter;
}
//Deletes the first node divisible by six
//Purposefully does not use helper functions
struct node *delete_div_6(struct node *head) {
struct node *current = head;
while (current->next != NULL) {
if (current->next->data % 6 == 0) {
struct node *next = current->next->next;
struct node *node_to_delete = current->next;
free(node_to_delete);
current->next = next;
return head;
}
current = current->next;
}
return head;
}
//Returns the difference between the largest and smallest element
//If there's only one element, return that element
int range(struct node *head) {
return 0;
}
//Merges two linked lists into one linked list, and frees the second
struct node *merge_linked_lists(struct node *head1, struct node *head2) {
return head1;
}
int main(void) {
// the first node in a linked list is the head of our list.
struct node *head = create_node(11);
// create the next few nodes
struct node *second_node = create_node(8);
struct node *third_node = create_node(7);
struct node *fourth_node = create_node(15);
struct node *fifth_node = create_node(13);
struct node *sixth_node = create_node(1);
struct node *seventh_node = create_node(54);
struct node *eigth_node = create_node(35);
// we need to LINK the nodes in the linked list.
// the head node (11) should point to the second node
head = insert_in_order(head, second_node);
head = insert_in_order(head, third_node);
head = insert_in_order(head, fourth_node);
head = insert_in_order(head, fifth_node);
head = insert_in_order(head, sixth_node);
head = insert_in_order(head, seventh_node);
head = insert_in_order(head, eigth_node);
// and so on.
struct node *head2 = create_node(100);
struct node *new_2 = create_node(150);
struct node *new_3 = create_node(200);
struct node *new_4 = create_node(250);
head2->next = new_2;
head2->next->next = new_3;
head2->next->next->next = new_4;
print_linked_list(head);
//head = reverse_linked_list(head);
print_linked_list(head2);
head = delete_div_6(head);
print_linked_list(head);
//printf("%d nodes were divisible by 6 in my linked list\n", count_of_6);
free_all_nodes(head);
free_all_nodes(head2);
return 0;
}
// main.c
// Sofia De Bellis
// Simple Spotify
#include <stdio.h>
#include "spotify.h"
int main(void) {
// Initialize the spotify system
struct spotify *spotify = initialise_spotify();
// Create multiple playlists and add them to spotify
add_playlist("COMP(1511|1911)'s Favourites", spotify);
add_playlist("K-Pop Hits", spotify);
add_playlist("Chill Vibes", spotify);
// // Add songs to the favourites playlist
add_song("COMP(1511|1911)'s Favourites", "Touch", KPOP, "Katseye", 129, spotify);
add_song("COMP(1511|1911)'s Favourites", "Ms Jackon", HIPHOP, "Outkast", 299, spotify);
add_song("COMP(1511|1911)'s Favourites", "Love Story", POP, "Taylor Swift", 230, spotify);
add_song("COMP(1511|1911)'s Favourites", "Golden", KPOP, "HUNTR/X", 180, spotify);
// Add songs to the K-Pop playlist
add_song("K-Pop Hits", "Dynamite", KPOP, "BTS", 199, spotify);
add_song("K-Pop Hits", "Pink Venom", KPOP, "BLACKPINK", 195, spotify);
add_song("K-Pop Hits", "Touch", KPOP, "Katseye", 129, spotify);
// Add songs to the chill playlist
add_song("Chill Vibes", "Kyoto", INDIE, "Phoebe Bridgers", 242, spotify);
add_song("Chill Vibes", "Good Days", HIPHOP, "SZA", 260, spotify);
print_spotify(spotify);
// // Remove songs from the favourites playlist
remove_song(spotify, "COMP(1511|1911)'s Favourites", "Touch");
remove_song(spotify, "COMP(1511|1911)'s Favourites", "Good Days");
print_spotify(spotify);
print_songs_of_genre(spotify, KPOP);
merge_playlists(spotify, "COMP(1511|1911)'s Favourites", "K-Pop Hits");
print_spotify(spotify);
delete_spotify(spotify);
return 0;
}
ELF >