explain this code:

#include <stdio.h>
#include <stdlib.h>

struct Tuple {
    int x;
    int y;
};

struct Node {
    struct Tuple data;
    struct Node* next;
};

typedef struct Tuple Tuple;
typedef struct Node Node;

Node* createNode(Tuple data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

void printList(Node* head) {
    Node* current = head;
    printf("[ ");
    while (current != NULL) {
        printf("(%d,%d) ", current->data.x, current->data.y);
        current = current->next;
    }
    printf("]\n");
}

void deleteNode(Node** head, Tuple data) {
    Node* current = *head;
    Node* prev = NULL;

    while (current != NULL) {
        if (current->data.x == data.x && current->data.y == data.y) {
            if (prev == NULL) {
                *head = current->next;
            } else {
                prev->next = current->next;
            }
            free(current);
            return;
        }
        prev = current;
        current = current->next;
    }
}

int main() {
    Node* originalList = NULL;

    originalList = createNode((Tuple){3, 6});
    originalList->next = createNode((Tuple){5, 4});
    originalList->next->next = createNode((Tuple){4, 11});
    originalList->next->next->next = createNode((Tuple){13, 30});
    originalList->next->next->next->next = createNode((Tuple){12, 2});
    originalList->next->next->next->next->next = createNode((Tuple){10, 1});

    printf("Original List: ");
    printList(originalList);

    Node* current = originalList;
    while (current != NULL) {
        printf("Deleted value: (%d,%d)\n", current->data.x, current->data.y);
        Node* next = current->next;
        free(current);
        current = next;
    }
    originalList = NULL;
    printf("List after deleting all items: ");
    printList(originalList);

    originalList = createNode((Tuple){3, 6});
    originalList->next = createNode((Tuple){5, 4});
    originalList->next->next = createNode((Tuple){4, 11});
    originalList->next->next->next = createNode((Tuple){13, 30});
    originalList->next->next->next->next = createNode((Tuple){12, 2});
    originalList->next->next->next->next->next = createNode((Tuple){10, 1});
    printf("Restored List: ");
    printList(originalList);

    Tuple searchTuple = {5, 4};
    current = originalList;
    Node* prev = NULL;
    while (current != NULL) {
        if (current->data.x == searchTuple.x && current->data.y == searchTuple.y) {
            printf("Element found: (%d,%d)\n", current->data.x, current->data.y);
            deleteNode(&originalList, searchTuple);
            printf("List after deleting an item: ");
            printList(originalList);
            
        }
        prev = current;
        current = current->next;
    }
    if (current == NULL) {
        printf("Element not found.\n");
    }

    int swapped;
    Node* lastNode = NULL;
    do {
        swapped = 0;
        current = originalList;
        while (current->next != lastNode) {
            if (current->data.x > current->next->data.x) {
                Tuple temp = current->data;
                current->data = current->next->data;
                current->next->data = temp;
                swapped = 1;
            }
            current = current->next;
        }
        lastNode = current;
    } while (swapped);
    printf("List after sorting the data: ");
    printList(originalList);

    Node* prevNode = NULL;
    Node* nextNode = NULL;
    current = originalList;
    while (current != NULL) {
        nextNode = current->next;
        current->next = prevNode;
        prevNode = current;
        current = nextNode;
       
    }
    originalList = prevNode;
    printf("List after reversing the data: ");
    printList(originalList);

    while (originalList != NULL) {
        Node* next = originalList->next;
        free(originalList);
        originalList = next;
    }

    return 0;
}