#include<stdio.h>
#include<cstdlib>

// Ein Schlangenelement
struct QueueElem {
    QueueElem* next;  // Zeiger auf nächstes Element
    int value;          // Daten zu diesem Element  
} ;

// Eine Schlange
struct Queue {
    int count;          // Anzahl Elemente in der Liste
    QueueElem* first; // Zeiger auf erstes Element der Liste
} ;

// Initialisiere eine Schlange
void empty_queue (Queue* l)
{
    l->first = 0;   // 0 ist keine gueltige Adresse: Liste ist leer
    l->count = 0;
}

// Fuege ein Element ans Ende der Schlange an
void add_to_queue (Queue* queue, QueueElem* elem)
{
    // Laufpointer
    QueueElem* current = queue->first;
    if (queue->first == 0) { // if queue is empty, put the new element as the first one
        queue->first = elem;
        return;
    }
    // find last element of list
    while (current->next != 0) {
        current = current->next;
    }
    current->next = elem; // set new element as the follower of the old last one
    queue->count = queue->count + 1; // increment queue size
}

// Entferne das erste Element der Schlange
QueueElem* remove_from_queue(Queue* queue)
{
    QueueElem* p;  // das entfernte Element
    if (queue->first == 0) { // check if list is empty
        return p;  // then just return null pointer
    } else {
        p = queue->first; // return the first element of the queue
        queue->first = p->next; // set the second to be the new first
        queue->count = queue->count-1; // decrement queue size
        return p; // return the removed element
    }
}

// print a queue
void print_queue(Queue* queue) {
    // index pointer
    QueueElem* current = queue->first;
    printf("Queue: ");
    // print every element until the last
    while (current != 0) {
        printf("%d ", current->value);
        current = current->next;
    }
    printf("\n");
}

int main() {
    // create a queue
    Queue* queue = new Queue();
    empty_queue(queue);
    // and some elements
    for (int i = 0; i < 100000; i++) {
        QueueElem* elem = new QueueElem();
        elem -> value = rand();
        add_to_queue(queue, elem);
    }
    // and remove them again
    for (int i = 0; i < 100000; i++) {
        remove_from_queue(queue);
    }
    // check if queue is empty
    print_queue(queue);
}
