Files
learning/c/isp-ws25/weeklies/week10/w10ex02.c

125 lines
3.4 KiB
C
Executable File

/*
In this task, you should extend the playlist program from the last lecture.
The playlist is implemented as a linked list of songs,
where each song has an artist, a title, a length,
and a pointer to the next element in the linked list.
For details about the implementation have a look at the corresponding lecture.
The given code already covers creating and printing the linked list.
Your task is to implement the function deleteSong(),
which takes the head of the linked list and the index that should be removed.
Removing an element from a linked list is efficient but requires careful implementation.
Before coding, it's helpful to visualize the process with a diagram.
To keep the code snippet short, you can assume that
- malloc will always succeed (i.e., it will never return NULL) and
- the user will always provide a valid index to remove an element from the linked list.
This is an example: The yellow-marked content represents a user input.
0: Bob Dylan - Like A Rolling Stone (369)
1: AJR - Humpty Dumpty (217)
2: Wham! - Last Christmas (322)
3: Eminem - Lose Yourself (401)
Which element do you want to remove? 1
0: Bob Dylan - Like A Rolling Stone (369)
1: Wham! - Last Christmas (322)
2: Eminem - Lose Yourself (401)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _Song_
{
char artist_[50];
char title_[50];
short length_;
struct _Song_* next_;
} Song;
void printSong(Song* head)
{
Song* current = head;
int index = 0;
while(current != NULL)
{
printf("%d: %s - %s (%d)\n", index++, current->artist_, current->title_, current->length_);
current = current->next_;
}
}
Song* createAndAddSong(Song* head, char* artist, char* title, short len)
{
Song* new_song = malloc(sizeof(Song)); // usually you should check for NULL here and react accordingly
strcpy(new_song->artist_, artist);
strcpy(new_song->title_, title);
new_song->length_ = len;
new_song->next_ = NULL;
if(head == NULL)
{
head = new_song;
return head;
}
Song* current = head;
while(current->next_ != NULL)
{
current = current->next_;
}
current->next_ = new_song;
return head;
}
void deleteSong(Song** head, int index_to_remove)
{
if (head == NULL || *head == NULL) return; // nothing to remove
if (index_to_remove < 0) return; // invalid index
if (index_to_remove == 0)
{
Song *free_head = *head;
*head = free_head->next_;
free(free_head);
return;
}
Song *previous = *head;
Song *song_to_remove = *head;
for (int index = 0; index < index_to_remove; index++)
{
if (song_to_remove == NULL) return; // index out of range
previous = song_to_remove;
song_to_remove = song_to_remove->next_;
}
if (song_to_remove == NULL) return; // index out of range
previous->next_ = song_to_remove->next_;
free(song_to_remove);
}
int main(void)
{
// usually you should check for NULL at each call and react accordingly
Song* head = createAndAddSong(NULL, "Bob Dylan", "Like A Rolling Stone", 369);
head = createAndAddSong(head, "AJR", "Humpty Dumpty", 217);
head = createAndAddSong(head, "Wham!", "Last Christmas", 322);
head = createAndAddSong(head, "Eminem", "Lose Yourself", 401);
printSong(head);
int nr_to_remove = 0;
printf("Which element do you want to remove? ");
scanf("%d", &nr_to_remove);
deleteSong(&head, nr_to_remove);
printSong(head);
// you also should free the linked list
return 0;
}