Untitled

 avatar
unknown
plain_text
14 days ago
4.4 kB
7
Indexable
#include <iostream>
#include <memory>
#include <vector>
#include <iterator>
#include <algorithm>

template <typename T, size_t MaxElementsPerNode = 5, typename Allocator = std::allocator<T>>
class UnrolledLinkedList {
public:
    // Внутренняя структура ноды
    struct Node {
        std::vector<T, Allocator> elements;
        Node* next;
        Node* prev;

        Node() : next(nullptr), prev(nullptr) {}
    };

    // Итератор
    class iterator {
    public:
        using iterator_category = std::bidirectional_iterator_tag;
        using value_type = T;
        using difference_type = std::ptrdiff_t;
        using pointer = T*;
        using reference = T&;

        iterator(Node* node = nullptr, size_t index = 0) : current_node(node), current_index(index) {}

        reference operator*() const {
            return current_node->elements[current_index];
        }

        pointer operator->() const {
            return &current_node->elements[current_index];
        }

        iterator& operator++() {
            if (++current_index >= current_node->elements.size()) {
                current_node = current_node->next;
                current_index = 0;
            }
            return *this;
        }

        iterator operator++(int) {
            iterator temp = *this;
            ++(*this);
            return temp;
        }

        iterator& operator--() {
            if (current_index == 0) {
                current_node = current_node->prev;
                current_index = current_node->elements.size() - 1;
            } else {
                --current_index;
            }
            return *this;
        }

        iterator operator--(int) {
            iterator temp = *this;
            --(*this);
            return temp;
        }

        bool operator==(const iterator& other) const {
            return current_node == other.current_node && current_index == other.current_index;
        }

        bool operator!=(const iterator& other) const {
            return !(*this == other);
        }

    private:
        Node* current_node;
        size_t current_index;
    };

    // Обратный итератор
    using reverse_iterator = std::reverse_iterator<iterator>;

    // Конструкторы
    UnrolledLinkedList() : head(nullptr), tail(nullptr), size_(0) {}

    ~UnrolledLinkedList() {
        clear();
    }

    // Методы контейнера
    void push_back(const T& value) {
        if (!tail || tail->elements.size() >= MaxElementsPerNode) {
            Node* new_node = new Node();
            if (tail) {
                tail->next = new_node;
                new_node->prev = tail;
            } else {
                head = new_node;
            }
            tail = new_node;
        }
        tail->elements.push_back(value);
        ++size_;
    }

    void pop_back() {
        if (!tail) return;
        tail->elements.pop_back();
        if (tail->elements.empty()) {
            Node* prev_node = tail->prev;
            delete tail;
            tail = prev_node;
            if (tail) {
                tail->next = nullptr;
            } else {
                head = nullptr;
            }
        }
        --size_;
    }

    iterator begin() {
        return iterator(head, 0);
    }

    iterator end() {
        return iterator(nullptr, 0);
    }

    reverse_iterator rbegin() {
        return reverse_iterator(end());
    }

    reverse_iterator rend() {
        return reverse_iterator(begin());
    }

    size_t size() const {
        return size_;
    }

    bool empty() const {
        return size_ == 0;
    }

    void clear() {
        while (head) {
            Node* next_node = head->next;
            delete head;
            head = next_node;
        }
        tail = nullptr;
        size_ = 0;
    }

private:
    Node* head;
    Node* tail;
    size_t size_;
};

int main() {
    UnrolledLinkedList<int> ull;
    ull.push_back(1);
    ull.push_back(2);
    ull.push_back(3);
    ull.push_back(4);
    ull.push_back(5);
    ull.push_back(6);

    for (auto it = ull.begin(); it != ull.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    for (auto it = ull.rbegin(); it != ull.rend(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    return 0;
}
Editor is loading...
Leave a Comment