Forwardlist 구현
#pragma once
#include <stddef.h>
class ForwardList
{
// 연결 리스트에서 데이터를 저장하기 위한 타입
// 즉, 연결 리스트는 데이터를 직접적으로 다루는 것이 아니라
// Node라는 것으로 다룹니다.
struct Node
{
Node(int data = 0, Node* next = nullptr);
Node(const Node&) = delete;
Node& operator=(const Node&) = delete;
~Node();
int Data = 0; // 실제 데이터
Node* Next = nullptr; // 다음 원소
};
public:
// 데이터를 수정할 수 없는 반복자
// const int*
class const_iterator
{
public:
const_iterator(Node* p = nullptr);
~const_iterator();
const int& operator*() const; // 역참조
const int* operator->() const; // 멤버 접근
const_iterator& operator++(); // 전위 증가 연산자
const_iterator operator++(int); // 후위 증가 연산자
bool operator==(const const_iterator& rhs) const;
bool operator!=(const const_iterator& rhs) const;
bool operator==(nullptr_t p) const;
bool operator!=(nullptr_t p) const;
public:
// 데이터 수정이 가능한 반복자
// int*
Node* _p = nullptr;
};
class iterator : public const_iterator
{
public:
//using const_iterator::const_iterator;
iterator(Node* p = nullptr);
int& operator*() const;
int* operator->() const;
iterator& operator++();
iterator operator++(int);
};
// 기본 생성자
ForwardList();
// count만큼의 요소를 갖고 있는 컨테이너를 만드는 생성자
explicit ForwardList(size_t count);
// 복사 생성자.
ForwardList(const ForwardList& other);
// 할당 연산자
ForwardList& operator=(const ForwardList& rhs);
// 소멸자
~ForwardList();
// 첫 번째 요소를 반환한다.
int& front();
const int& front() const;
// 시작 전 요소를 가리키는 반복자를 반환한다.
iterator before_begin();
const_iterator before_begin() const;
// 시작 요소를 가리키는 반복자를 반환한다.
iterator begin();
const_iterator begin() const;
// 끝 다음 요소를 가리키는 반복자를 반환한다.
iterator end();
const_iterator end() const;
// pos 다음에 value를 삽입한다.
// 삽입된 요소를 가리키는 반복자를 반환한다.
iterator insert_after(const_iterator pos, int value);
// pos 다음 요소를 삭제한다.
// 삭제된 요소의 다음 요소를 가리키는 반복자를 반환한다.
// 아무 요소도 없으면 end()를 반환한다.
iterator erase_after(const_iterator pos);
// 시작 요소에 value를 삽입한다.
void push_front(int value);
// 시작 요소를 제거한다.
void pop_front();
// 컨테이너가 비었는지 판단한다.
bool empty() const;
// 컨테이너를 비워버린다.
void clear();
// value가 있는지 검사한다.
bool contains(int value) const;
private:
// 더미 노드: 실제 데이터를 담지 않응. 오로지 구현의 편의성만을 위해서 존재
Node* _head = new Node(); // before_begin()
// 더미 노드
// Node* _end = new Node(); // end() NULL 이 대체
};
#include "ForwardListNode.h"
#include <utility>
ForwardList::Node::Node(int data, Node* next)
:Data(data), Next(next)
{
}
ForwardList::Node::~Node()
{
Next = nullptr;
}
ForwardList::const_iterator::const_iterator(Node* p)
:_p(p)
{
}
ForwardList::const_iterator::~const_iterator()
{
_p = nullptr;
}
const int& ForwardList::const_iterator::operator*() const
{
return _p->Data;
}
const int* ForwardList::const_iterator::operator->() const
{
return &(_p->Data);
}
ForwardList::const_iterator&
ForwardList::const_iterator::operator++()
{
// ++p?
_p = _p->Next;
return *this;
}
ForwardList::const_iterator
ForwardList::const_iterator::operator++(int)
{
// p++
// 1. p를 1 증가 시키고
// 2. 이전 p를 반환
const_iterator temp = *this;
_p = _p->Next;
return temp;
}
bool ForwardList::const_iterator::operator==(const const_iterator& rhs) const
{
if (_p == rhs._p)
{
return true;
}
else
{
return false;
}
}
bool ForwardList::const_iterator::operator!=(const const_iterator& rhs) const
{
return !(*this == rhs); // 보통 같지 않다 구현할 떄 다 요렇게 함
}
bool ForwardList::const_iterator::operator==(nullptr_t p) const
{
if (_p == nullptr)
{
return true;
}
else
{
return false;
}
// C++ 11 부터 나왔고, NULL의 모호함 때문에 나왔다.
// NULL 정수로서의 0도 되고, 포인터로서의 NULL도 되기 때문에
}
bool ForwardList::const_iterator::operator!=(nullptr_t p) const
{
return !(*this == nullptr);
}
ForwardList::iterator::iterator(Node* p)
: const_iterator(p)
{
}
int& ForwardList::iterator::operator*() const
{
return (int&)const_iterator::operator*();
}
int* ForwardList::iterator::operator->() const
{
return (int*)const_iterator::operator->();
}
ForwardList::iterator&
ForwardList::iterator::operator++()
{
const_iterator::operator++();
return *this;
}
ForwardList::iterator
ForwardList::iterator::operator++(int)
{
iterator temp = *this;
const_iterator::operator++();
return temp;
}
ForwardList::ForwardList()
{
// _head -> []
// _end -> []
// [] -> []
//_head->Next = _end;
// begin() == end()
// _head->Next == nullptr
// _head = new node(0, nullptr);
}
ForwardList::ForwardList(size_t count)
: ForwardList()
{
for (size_t i = 0; i < count; i++)
{
push_front(0);
}
}
ForwardList::ForwardList(const ForwardList& other)
:ForwardList()
{
iterator inserted = before_begin();
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
{
inserted = insert_after(inserted, *iter);
}
}
ForwardList& ForwardList::operator=(const ForwardList& rhs)
{
if (&rhs != this)
{
ForwardList temp(rhs);
std::swap(_head, temp._head);
}
return *this;
}
ForwardList::~ForwardList()
{
clear();
delete _head;
_head = nullptr;
}
int& ForwardList::front()
{
return *begin();
}
const int& ForwardList::front() const
{
return *begin();
}
ForwardList::iterator ForwardList::before_begin()
{
return _head;
}
ForwardList::const_iterator ForwardList::before_begin() const
{
return _head;
}
ForwardList::iterator ForwardList::begin()
{
return _head->Next;
}
ForwardList::const_iterator ForwardList::begin() const
{
return _head->Next;
}
ForwardList::iterator ForwardList::end()
{
return nullptr;
}
ForwardList::const_iterator ForwardList::end() const
{
return nullptr;
}
ForwardList::iterator ForwardList::insert_after(const_iterator pos, int value)
{
// [] -> [] -> [] -> []
// pos Next
// value
Node* newNode = new Node(value);
Node* where = pos._p;
newNode->Next = where->Next;
where->Next = newNode;
return newNode;
}
ForwardList::iterator ForwardList::erase_after(const_iterator pos)
{
// [] -> [] -> [] -> [*]
// pos removed Next
// 예외처리
Node* where = pos._p;
Node* removed = where->Next;
where->Next = removed->Next;
// [] -> [] -> [*]
// where
// [] removed
delete removed;
return where->Next;
}
void ForwardList::push_front(int value)
{
insert_after(before_begin(), value);
}
void ForwardList::pop_front()
{
erase_after(before_begin());
}
bool ForwardList::empty() const
{
if (_head->Next == nullptr) // if(begin() == nullptr)
{
return true;
}
else
{
return false;
}
}
void ForwardList::clear()
{
while (false == empty())
{
pop_front();
}
}
bool ForwardList::contains(int value) const
{
for (const_iterator iter = begin(); iter != end(); ++iter)
{
if (*iter == value)
{
return true;
}
}
return false;
}
Main.cpp
#include <iostream>
#include "ForwardListNode.h"
#include <forward_list>
using namespace std;
int main()
{
std::forward_list<int> flist;
ForwardList mylist;
flist.push_front(1); // [1]
mylist.push_front(1); // [1]
if (flist.front() == mylist.front())
{
std::cout << "같음";
}
forward_list<int>::iterator iter = flist.begin();
ForwardList::iterator liter = mylist.begin();
mylist.insert_after(mylist.begin(), 3); // [1] [] [3]
liter++;
cout << *liter << "\\n";
std::cout << "myflist 첫번째 값: " << mylist.front() << "\\n";
mylist.clear();
if (mylist.empty())
{
cout << "mylist는 비었음." << "\\n";
}
for (int i = 0; i < 10; i++)
{
mylist.push_front(i);
}
cout << "\\n" << "테스트: ";
for (liter = mylist.begin(); liter != mylist.end(); ++liter)
{
cout << "[" << * liter << "]" << " ";
}
mylist.erase_after(mylist.begin());
}
List 구현하기
#include <algorithm>
// int를 template<typename T> 로 바꾸면 댄다 템플릿 할라면
class List
{
public:
struct Node
{
Node(int data = 0, Node* prev = nullptr, Node* next = nullptr);
Node(const Node&) = delete;
Node& operator=(const Node&) = delete;
~Node() = default;
int Data = 0;
Node* Next = nullptr;
Node* Prev = nullptr;
};
public:
class const_iterator
{
public:
const_iterator(Node* p = nullptr);
~const_iterator();
const int& operator*() const;
const int* operator->() const;
const_iterator& operator++();
const_iterator operator++(int);
const_iterator& operator--();
const_iterator operator--(int);
bool operator==(const const_iterator& rhs) const;
bool operator!=(const const_iterator& rhs) const;
bool operator==(nullptr_t p) const;
bool operator!=(nullptr_t p) const;
public:
Node* _p = nullptr; // 데이터 수행이 가능한 반복자
};
class iterator : public const_iterator
{
public:
using const_iterator::const_iterator;
int& operator*() const;
int* operator->() const;
iterator& operator++();
iterator operator++(int);
iterator& operator--();
iterator operator--(int);
};
// 기본 생성자
List(); // = default;
// count만큼의 요소를 갖고 있는 컨테이너를 만드는 생성자
explicit List(size_t count);
// 복사 생성자.
List(const List& other);
// 할당 연산자
List& operator=(const List& rhs);
// 소멸자
~List();
// 첫 번째 요소를 반환한다.
int& front();
const int& front() const;
// 마지막 요소를 반환한다.
int& back();
const int& back() const;
// 시작 요소를 가리키는 반복자를 반환한다.
// 리스트가 비어있다면 end()와 같다.
iterator begin();
const_iterator begin() const;
// 끝 다음 요소를 가리키는 반복자를 반환한다.
iterator end();
const_iterator end() const;
// pos 이전에 value를 삽입한다.
// 삽입된 요소를 가리키는 반복자를 반환한다.
iterator insert(iterator pos, int value);
// pos 를 삭제한다.
// 삭제된 요소의 다음 요소를 가리키는 반복자를 반환한다.
// 아무 요소도 없으면 end()를 반환한다.
iterator erase(iterator pos);
// 시작에 value를 삽입한다.
void push_front(int value);
// 끝에 value를 삽입한다.
void push_back(int value);
// 시작 요소를 제거한다.
void pop_front();
// 끝 요소를 제거한다.
void pop_back();
// 컨테이너가 비었는지 판단한다.
bool empty() const;
// 리스트 안에 있는 요소의 개수를 반환한다.
size_t size() const;
// 컨테이너를 비워버린다.
void clear();
// 해당 value가 있는지 체크한다.
bool contains(int value) const;
private:
Node* _end = new Node(); // 더미 노드; end()
//Node* _begin = _end; // 헷갈리면 _head를 begin으로 바꿔도 된다.
size_t _size = 0;
};
#include "List.h"
using namespace std;
List::Node::Node(int data, Node* prev, Node* next)
: Data(data), Prev(prev), Next(next)
{
}
List::const_iterator::const_iterator(Node* p)
: _p(p)
{
}
List::const_iterator::~const_iterator()
{
_p = nullptr;
}
const int& List::const_iterator::operator*() const
{
return _p->Data;
}
const int* List::const_iterator::operator->() const
{
return &(_p->Data);
}
List::const_iterator& List::const_iterator::operator++()
{
_p = _p->Next;
return *this;
}
List::const_iterator List::const_iterator::operator++(int)
{
iterator temp = _p;
_p = _p->Next;
return temp;
}
List::const_iterator& List::const_iterator::operator--()
{
_p = _p->Prev;
return *this;
}
List::const_iterator List::const_iterator::operator--(int)
{
iterator temp = _p;
_p = _p->Prev;
return temp;
}
bool List::const_iterator::operator==(const const_iterator& rhs) const
{
if (_p == rhs._p)
{
return true;
}
else
{
return false;
}
}
bool List::const_iterator::operator!=(const const_iterator& rhs) const
{
return !(*this == rhs);
}
bool List::const_iterator::operator==(nullptr_t p) const
{
return (int&)const_iterator::operator*();
}
bool List::const_iterator::operator!=(nullptr_t p) const
{
return !(*this == nullptr);
}
int& List::iterator::operator*() const
{
return (int&)const_iterator::operator*();
}
int* List::iterator::operator->() const
{
return (int*)const_iterator::operator->();
}
List::iterator&
List::iterator::operator++()
{
const_iterator::operator++();
return *this;
}
List::iterator
List::iterator::operator++(int)
{
iterator temp = *this;
const_iterator::operator++();
return temp;
}
List::iterator&
List::iterator::operator--()
{
const_iterator::operator--();
return *this;
}
List::iterator
List::iterator::operator--(int)
{
iterator temp = *this;
const_iterator::operator--();
return temp;
}
List::List()
{
_end->Next = _end;
_end->Prev = _end;
}
List::List(size_t count)
:List()
{
for (size_t i = 0; i < count; i++)
{
push_front(0);
}
}
List::List(const List& other)
:List()
{
iterator inserted = --begin();
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
{
inserted = insert(inserted, *iter);
}
}
List& List::operator=(const List& rhs)
{
if (this != &rhs)
{
List temp(rhs);
//swap(_end, temp._end);
//swap(_begin, temp._begin);
//swap(_size, temp._size);
std::swap(_end->Next, temp._end->Next);
}
return *this;
}
List::~List()
{
clear();
/*delete _end;
_end = nullptr;*/
//_begin = nullptr;
}
int& List::front()
{
return *begin();
}
const int& List::front() const
{
return *begin();
}
int& List::back()
{
return *(--end());
}
const int& List::back() const
{
return *(--end());
}
List::iterator List::begin()
{
return iterator(_end->Next);
}
List::const_iterator List::begin() const
{
return const_iterator(_end->Next);
}
List::iterator List::end()
{
return iterator(_end);
}
List::const_iterator List::end() const
{
return const_iterator(_end);
}
List::iterator List::insert(iterator pos, int value)
{
Node* nextNode = pos._p;
Node* prevNode = pos._p->Prev;
Node* newNode = new Node(value, prevNode, nextNode);
/*newNode->Prev = prevNode;
newNode->Next = nextNode;*/
prevNode->Next = newNode;
nextNode->Prev = newNode;
++_size;
return newNode;
}
List::iterator List::erase(List::iterator pos)
{
Node* removed = pos._p;
Node* removedPrev = removed->Prev;
Node* removedNext = removed->Next;
removedPrev->Next = removedNext;
removedNext->Prev = removedPrev;
delete removed;
--_size;
return removedNext;
}
void List::push_front(int value)
{
insert(begin(), value);
}
void List::push_back(int value)
{
insert(end(), value);
}
void List::pop_front()
{
erase(begin());
}
void List::pop_back()
{
/*iterator iter = end();
--iter;
erase(iter);*/
erase(_end->Prev);
}
bool List::empty() const
{
if (_size == 0)
{
return true;
}
else
{
return false;
}
}
size_t List::size() const
{
return _size;
}
void List::clear()
{
while (empty() == false)
{
pop_front();
}
}
bool List::contains(int value) const
{
for (const_iterator iter = begin(); iter != end(); ++iter)
{
if (*iter == value)
{
return true;
}
}
return false;
}
#include <iostream>
#include <list>
#include "List.h"
using namespace std;
int main()
{
List mylist;
std::list<int> flist;
/*mylist.push_front(1);
flist.push_front(1);*/
auto iter = mylist.begin();
cout << "현재 mylist 첫번째 값: " << *iter << "\\n";
for (int i = 0; i < 10; i++)
{
mylist.push_front(i);
// [1] [1] [2] ... [8] [9]
flist.push_front(1);
}
if (flist.front() == mylist.front())
{
cout << "같음\\n";
}
for (iter = mylist.begin(); iter != mylist.end(); ++iter)
{
cout << "[" << *iter << "]" << " ";
}
}