시퀀스 컨테이너이지만 vector와 다르게 배열이 아닌 노드 기반으로 구현되어있다. 즉, 연속된 메모리 공간이 아니다.

 

 

구현 사항

 

 

코드

더보기
#include "GlobalDefine.h"

template<typename T>
class MyLinkedList {
private:
    struct Node {
    public:
        Node() = delete;

        explicit Node(const T& d) :
            data(d),
            prev(nullptr),
            next(nullptr)
        {
            std::cout << "왼값 노드 생성" << std::endl;
        }

        explicit Node(T&& d) noexcept :
            data(std::move(d)),
            prev(nullptr),
            next(nullptr)
        {
            std::cout << "오른값 노드 생성" << std::endl;
        }

        explicit Node(const Node& _node) :
            data(_node.data),
            prev(nullptr),
            next(nullptr)
        {
            std::cout << "노드 복사" << std::endl;
        }

        explicit Node(Node&& _node) noexcept :
            data(std::move(_node.data)),
            prev(nullptr),
            next(nullptr)
        {
            std::cout << "노드 이동" << std::endl;
        }
        
        ~Node() { SAFE_DELETE(next) }

    public:
        Node& operator=(const Node& _node)
        {
            data = _node.data;
            prev = nullptr;
            next = nullptr;
        }

        Node& operator=(Node&& _node)
        {
            data = std::move(_node.data);
            prev = std::move(_node.prev);
            next = std::move(_node.next);

            _node.data = 0;
            _node.prev = nullptr;
            _node.next = nullptr;
        }

    public:
        T data;
        Node* prev;
        Node* next;
    };

public:
    explicit MyLinkedList() : 
        head_(nullptr),
        tail_(head_),
        current_(head_),
        size_(0)
    {}

    explicit MyLinkedList(const MyLinkedList& list) :
        head_(nullptr),
        tail_(head_),
        current_(head_),
        size_(0)
    {
        this->operator=(list);
    }

    explicit MyLinkedList(MyLinkedList&& list) noexcept :
        head_(list.head_),
        tail_(list.tail_),
        current_(head_),
        size_(list.size_)
    {
        this->operator=(std::forward<MyLinkedList>(list));
    }

    ~MyLinkedList() { SAFE_DELETE(head_); }

public:
    MyLinkedList& operator=(const MyLinkedList& list) {
        std::cout << "왼값 복사 연산" << std::endl;
        Node* node = list.head_;

        while (node) {
            push_back(node->data);
            node = node->next;
        }

        return *this;
    }

    MyLinkedList& operator=(MyLinkedList&& list) noexcept {
        std::cout << "오른값 이동 연산" << std::endl;
        head_ = list.head_;
        tail_ = list.tail_;
        current_ = list.current_;
        size_ = list.size_;

        list.head_ = nullptr;
        list.tail_ = nullptr;
        list.current_ = nullptr;
        list.size_ = 0;

        return *this;
    }

public:
    void push_front(const T& data) {
        Node* newNode = new Node(data);

        if (!head_) {
            head_ = tail_ = newNode;
        }
        else {
            newNode->next = head_;
            newNode->prev = nullptr;
            head_->prev = newNode;
            head_ = newNode;
        }
        ++size_;
    }

    void push_front(T&& data) noexcept {
        Node* newNode = new Node(std::move(data));

        if (!head_) {
            head_ = tail_ = newNode;
        }
        else {
            newNode->next = head_;
            newNode->prev = nullptr;
            head_->prev = newNode;
            head_ = newNode;
        }
        ++size_;
    }

    void push_back(const T& data) {
        Node* newNode = new Node(data);

        if (!tail_) {
            head_ = tail_ = newNode;
        }
        else {
            newNode->next = nullptr;
            newNode->prev = tail_;
            tail_->next = newNode;
            tail_ = newNode;
        }
        ++size_;
    }

    void push_back(T&& data) noexcept {
        Node* newNode = new Node(std::move(data));

        if (!tail_) {
            head_ = tail_ = newNode;
        }
        else {
            newNode->next = nullptr;
            newNode->prev = tail_;
            tail_->next = newNode;
            tail_ = newNode;
        }
        ++size_;
    }

    void pop_front() {
        Node* temp = head_;

        if (head_ != tail_) {
            head_->next->prev = nullptr;
            head_ = head_->next;
        }
        else {
            head_ = tail_ = nullptr;
        }

        temp->prev = nullptr;
        temp->next = nullptr;
        SAFE_DELETE(temp);
        --size_;
    }

    void pop_back() {
        Node* temp = tail_;

        if (tail_ != head_) {
            tail_->prev->next = nullptr;
            tail_ = tail_->prev;
        }
        else {
            head_ = tail_ = nullptr;
        }

        temp->prev = nullptr;
        temp->next = nullptr;
        SAFE_DELETE(temp);
        --size_;
    }

    void insert(const T& d)
    {
        if (!current_ || !current_->next) {
            push_back(std::forward<T>(d));
        }
        else {
            Node* temp = new Node(d);

            temp->next = current_->next;
            temp->prev = current_;
            current_->next->prev = temp;
            current_->next = temp;
            ++size_;
        }
    }

    void remove(const T& d)
    {
        Node* target = this->find(d);

        if (!target) return;

        if (!target->prev) {
            pop_front();
        }
        else if (!target->next) {
            pop_back();
        }
        else {
            target->prev->next = target->next;
            target->next->prev = target->prev;

            target->prev = nullptr;
            target->next = nullptr;

            SAFE_DELETE(target);
            --size_;
        }
    }

    T& front() {
        if (!head_) abort();
        return head_->data;
    }

    T& back() {
        if (!head_) abort();
        return tail_->data;
    }

    inline const int& size() const { return size_; }

private:
    Node* find(const int& data) {
        Node* n = head_;

        while (n && n->data != data)
            n = n->next;

        return n;
    }

private:
	Node* head_;
	Node* tail_;
    Node* current_;

	int size_;
};

'이론 > 자료구조&알고리즘' 카테고리의 다른 글

Queue  (0) 2023.02.15
Stack  (0) 2023.02.13
Divide & Conquer  (0) 2023.02.10
Recursion Basics  (0) 2023.02.09
Bit Manipulation  (0) 2023.02.09

+ Recent posts