template<
class Ty,
class Allocator = std::allocator<Ty>
> class list;
list
는 이중 연결리스트를 구현한 컨테이너이다. <list>
헤더에 구현되어 있다. forward_list
에 비해 더 많은 메모리를 사용하지만, 더 양방향 이동이 가능한다.
1. 사용
생성
다양한 방법을 이용해 생성 가능하다. 빈 컨테이너를 생성하거나, 미리 요소가 추가된 컨테이너를 생성할 수 있다. 각 생성자들은 Allocator를 추가적으로 받을 수 있다.
- 기본 생성자
- size를 전달하는 생성자
- initializer_list를 전달하는 생성자
- 시작과 끝의 이터레이터를 전달하는 생성자
- 복사 생성자
- 이동 생성자
// 1. 기본 생성자
// 아무것도 할당되지 않은 상태로 초기화.
list<int> list1;
// 2. size를 전달 받는 생성자.
// size만큼의 기본 값을 갖는 node를 리스트에 추가함.
list<int> list2(5); // 0 0 0 0 0
// 2-2. size와 초기화 값 v을 받는 생성자
// size만큼의 v값을 갖는 node를 리스트에 추가함.
list<int> list2_2(5, 1); // 1 1 1 1 1
// 3. initializer_list
list<int> list3 = { 1,2,3,4,5 }; // 1 2 3 4 5
list<int> list3_2{ 1,2,3,4,5 };
list<int> list3_3({ 1,2,3,4,5 });
// 4. iterator
list<int> list4(list3.begin(), list3.end()); // 1 2 3 4 5;
// 5. copy
list<int> list5(list4); // 1 2 3 4 5
// 6. move
list<int> list6(move(list5)); // 1 2 3 4 5
접근
접근 메서드로는 시작과 마지막 요소의 레퍼런스를 반환하는 front()
와 back()
만을 지원한다.
list<int> c{ 1,2,3,4,5 };
int& f = c.front(); // 1
int& b = c.back(); // 5
f = -1; // -1 2 3 4 5
b = 10; // -1 2 3 4 100
이터레이터
++
와 --
를 이용해 이동할 수 있다.
용량
size()
를 이용해 현재 보관된 요소의 개수를 알 수 있다. 그 외의 컨테이너가 비어있는지 확인할 수 있는 empty()
와 총 삽입 가능한 크기를 알려주는 max_size()
를 제공한다.
list<int> c{1,2,3,4,5};
c.size(); // 5
c.empty(); //false
c.max_size(); // 가용 가능한 메모리 총량
수정
insert()
나 emplace
를 통해 원하는 위치에 요소를 삽입할 수 있다. insert()
로는 1개 이상의 요소를 한 번에 삽입 가능하다. 원하는 위치의 요소 삭제는 erase()
를 이용한다. push_back()
, push_front()
, empace_back()
, emplace_front()
로 컨테이너 양쪽 끝 단에 요소를 삽입할 수 있다. pop_back()
과 pop_front()
로 컨테이너 양쪽 끝단에 있는 요소를 삭제할 수 있다.
list<int> c{ 1,2,3,4,5 };
auto iter = c.begin();
iter = next(iter, 2); // 3
iter = c.insert(iter, 11); // 1 2 11 3 4 5
iter = c.insert(iter, 12); // 1 2 12 11 3 4 5
iter = c.end();
c.emplace(iter, 6); // 1 2 12 11 3 4 5 6
c.emplace(iter, 7); // 1 2 12 11 3 4 5 6 7
iter = next(c.begin(), 2); // 12
iter = c.erase(iter); // 1 2 11 3 4 5 6 7
c.erase(iter); // 1 2 3 4 5 6 7
c.push_front(99); // 99 1 2 3 4 5 6 7
c.push_back(10); // 99 1 2 3 4 5 6 7 10
c.emplace_front(-1); // -1 99 1 2 3 4 5 6 7 10
c.emplace_back(-99); // -1 99 1 2 3 4 5 6 7 10 -99
c.pop_back(); // -1 99 1 2 3 4 5 6 7 10
c.pop_back(); // -1 99 1 2 3 4 5 6 7
c.pop_back(); // -1 99 1 2 3 4 5 6
c.pop_front(); // 99 1 2 3 4 5 6
c.pop_front(); // 1 2 3 4 5 6
resize로 보관된 요소의 수를 줄이거나, 일정한 값으로 채워 늘릭 수 있다. clear()
를 사용해 요소를 비울 수 있다.
//c ==> 1 2 3 4 5 6
c.resize(3, 0); // 1 2 3
c.resize(5); // 1 2 3 0 0
c.clear(); // empty
c.resize(5, 1); // 1 1 1 1 1
기타
list
역시 forward_list
와 마찬가지로 사용할 수 있는 독특한 연산이나, 이터레이터를 만족하지 못해서 사용할 수 없던 <algorithm>
의 함수들을 내부 메서드로 지원한다.
remove(e)
: e와 같은 요소들을 제거하고, 제거된 수를 반환한다.remove_if(f)
: 요소가 함수 f를 만족하면 제거하고, 제거된 수를 반환한다.reverse()
: 리스트의 순서를 뒤집는다.unique()
: 연속적으로 같은 값이 반복되어 있다면 하나를 제외하고 제거한다.sort()
: 리스트를 정렬한다.merge()
: 정렬된 두 리스트를 순서를 유지하며 합친다.splice_after()
: 다른 리스트를 가져와 이동시킨다.
list<int> c{ 3,3,9,2,3,4,1,1,7,8 };
auto n = c.remove(1); // 3 3 9 2 3 4 7 8
n; // 2
// 5보다 크면 삭제한다. // 3 3 2 3 4
n = c.remove_if([](int v) { return v > 5; });
n; // 3
c.reverse(); // 4 3 2 3 3
n = c.unique(); // 4 3 2 3
n; // 1
c.push_front(5); // 5 4 3 2 3
c.sort(); // 2 3 3 4 5
list<int> c2{ 0,1,10,11,12 };
// c2는 이동되어 empty가 된다.
c.merge(c2); // 0 1 2 3 3 4 5 10 11 12
c.resize(4); // 0 1 2 3
c2.assign({ 7,8,9 }); // 7 8 9
// c2는 이동된다. (c2가 empty가 된다.)
c.splice(c.begin(), c2); // 7 8 9 0 1 2 3