125 lines
3.4 KiB
C
Executable File
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;
|
|
}
|