# forward\_list

***

**1. Implementing a Stack with Forward Lists**

```cpp
struct Node {
    int value;
    Node* next;
};

class Stack {
public:
    Stack() : head(nullptr) {}
    void push(int value) {
        Node* new_node = new Node{value, head};
        head = new_node;
    }
    int pop() {
        if (head == nullptr) throw std::runtime_error("Empty stack");
        int value = head->value;
        Node* next_node = head->next;
        delete head;
        head = next_node;
        return value;
    }
    int peek() const {
        if (head == nullptr) throw std::runtime_error("Empty stack");
        return head->value;
    }
    bool empty() const { return head == nullptr; }

private:
    Node* head;
};
```

**2. Implementing a Queue with Forward Lists**

```cpp
struct Node {
    int value;
    Node* next;
};

class Queue {
public:
    Queue() : front(nullptr), back(nullptr) {}
    void push(int value) {
        Node* new_node = new Node{value, nullptr};
        if (back == nullptr) front = back = new_node;
        else {
            back->next = new_node;
            back = new_node;
        }
    }
    int pop() {
        if (front == nullptr) throw std::runtime_error("Empty queue");
        int value = front->value;
        Node* next_node = front->next;
        delete front;
        front = next_node;
        if (front == nullptr) back = nullptr;
        return value;
    }
    int peek() const {
        if (front == nullptr) throw std::runtime_error("Empty queue");
        return front->value;
    }
    bool empty() const { return front == nullptr; }

private:
    Node* front;
    Node* back;
};
```

**3. Creating a Doubly Linked List with Forward Lists**

```cpp
struct Node {
    int value;
    Node* next;
    Node* prev;
};

class DoublyLinkedList {
public:
    DoublyLinkedList() : head(nullptr), tail(nullptr) {}
    void push_front(int value) {
        Node* new_node = new Node{value, head, nullptr};
        if (head == nullptr) tail = new_node;
        else head->prev = new_node;
        head = new_node;
    }
    void push_back(int value) {
        Node* new_node = new Node{value, nullptr, tail};
        if (tail == nullptr) head = new_node;
        else tail->next = new_node;
        tail = new_node;
    }
    int pop_front() {
        if (head == nullptr) throw std::runtime_error("Empty list");
        int value = head->value;
        Node* next_node = head->next;
        delete head;
        head = next_node;
        if (head == nullptr) tail = nullptr;
        return value;
    }
    int pop_back() {
        if (tail == nullptr) throw std::runtime_error("Empty list");
        int value = tail->value;
        Node* prev_node = tail->prev;
        delete tail;
        tail = prev_node;
        if (tail == nullptr) head = nullptr;
        return value;
    }
    int peek_front() const {
        if (head == nullptr) throw std::runtime_error("Empty list");
        return head->value;
    }
    int peek_back() const {
        if (tail == nullptr) throw std::runtime_error("Empty list");
        return tail->value;
    }
    bool empty() const { return head == nullptr; }

private:
    Node* head;
    Node* tail;
};
```

**4. Implementing a Priority Queue with Forward Lists**

```cpp
struct Node {
    int priority;
    int value;
    Node* next;
};

class PriorityQueue {
public:
    PriorityQueue() : head(nullptr) {}
    void push(int priority, int value) {
        Node* new_node = new Node{priority, value, nullptr};
        if (head == nullptr || priority < head->priority) {
            new_node->next = head;
            head = new_node;
        } else {
            Node* prev_node = nullptr;
            Node* curr_node = head;
            while (curr_node != nullptr && priority >= curr_node->priority) {
                prev_node = curr_node;
                curr_node = curr_node->next;
            }
            new_node->next = curr_node;
            if (prev_node != nullptr) prev_node->next = new_node;
        }
    }
    Node pop() {
        if (head == nullptr) throw std::runtime_error("Empty queue");
        Node* popped_node = head;
        head = head->next;
        delete popped_node;
        return *popped_node;
    }
    Node peek() const {
        if (head == nullptr) throw std::runtime_error("Empty queue");
        return *head;
    }
    bool empty() const { return head == nullptr; }

private:
    Node* head;
};
```

**5. Creating a Circular Forward List**

```cpp
struct Node {
    int value;
    Node* next;
};

class CircularForwardList {
public:
    CircularForwardList() : head(nullptr) {}
    void push_back(int value) {
        Node* new_node = new Node{value, nullptr};
        if (head == nullptr) {
            head = new_node;
            new_node->next = head;
        } else {
            Node* curr_node = head;
            while (curr_node->next != head) {
                curr_node = curr_node->next;
            }
            new_node->next = head;
            curr_node->next = new_node;
        }
    }
    void push_front(int value) {
        Node* new_node = new Node{value, nullptr};
        if (head == nullptr) {
            head = new_node;
            new_node->next = head;
        } else {
            Node* curr_node = head;
            while (curr_node->next != head) {
                curr_node = curr_node->next;
            }
            new_node->next = head;
            curr_node->next = new_node;
            head = new_node;
        }
    }
    int pop_back() {
        if (head == nullptr) throw std::runtime_error("Empty list");
        Node* curr_node = head;
        Node* prev_node = nullptr;
        while (curr_node->next != head) {
            prev_node = curr_node;
            curr_node = curr_node->next;
        }
        if (prev_node != nullptr) prev_node->next = head;
        else head = nullptr;
        int value = curr_node

```
