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

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

// Eine Queue
struct Queue {
    int count;          // Anzahl Elemente in der queuee
    QueueElem* first; // Zeiger auf erstes Element der queue
    QueueElem* last;  // Zeiger auf letztes Element der queue
} ;


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

// Fuege neues Element am Ende der Schlange ein
void add_to_queue(Queue* queue, QueueElem* elem)
{
    if (queue->last == 0) {
        queue->first = elem;
        queue->last = elem;
    } else {
        queue->last->next = elem;
        elem->next = 0;
        elem->previous = queue->last;
        queue->last = elem;
    }
    queue->count = queue->count + 1;
}

// Remove last Element from queue and return it
QueueElem* remove_from_queue (Queue* queue)
{
    if (queue->first == 0) {
        return 0; // return null if queue is empty
    }
    QueueElem* p;
    p = queue->first;
    queue->first = p->next;
    queue->count = queue->count -1;
    return p;
}

// 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);
}
