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