list의 주요 인터페이스와 특징

cplusplus.com

list 는 sequence 컨테이너로 시퀀스 컨테이너가 갖는 모든 특징을 갖습니다. list 는 노드 기반 컨테이너로 at()과 [] 연산자가 없으며 임의 접근 반복자가 아닌 양방향 반복자를 제공합니다. 그래서 모든 원소를 탐색하려면 양방향 반복자의 연산인 ++, - -를 사용합니다.

list 의 가장 큰 특징 중 하나는 순차열 중간에 원소를 삽입 제거 하더라도 상수 시간 복잡도의 수행 성능을 보인다는 점입니다. vector 나 deque 처럼 원소를 밀어내지 않고 노드를 서로 연결하기만 하면 되기 때문입니다.

반복자 무효화

노드 기반 컨테이너의 삽입과 제거 동작은 반복자를 무효화시키지 않습니다. 반복자가 가리키는 원소 자체가 제거되지 않는 한 반복자가 가리키는 원소는 그대로 존재합니다. 하지만, 배열 기반 컨테이너 (vector, deque)의 반복자는 원소의 삽입과 제거 동작이 발생하면 메모리가 재할당되거나 원소가 이동할 수 있으므로 반복자가 무효화 됩니다.

list와 vector 의 remove

list 는 포인터 만 바꾸면 되지만 vector 는 다른 요소들을 한칸씩 뒤로 밀어야 한다.

list는 반복자를 이용해 우너소를 제거하는 erase() 말고도 원소의 값으로 원소를 제거하는 remove() 함수를 가지고 있습니다. remove() 멤버 함수는 컨테이너의 모든 원소를 순차적으로 검색하며 해당 원소를 제거합니다.

list의 remove()

lt.remove(10); // 10 원소의 노드를 모두 제거

list 의 remove() 는 erase()처럼 해당 값의 노드만을 제거하므로 속도가 빠르며 유일하게 list만이 remove() 멤버 함수를 가지므로 반복자가 아닌 원소의 값으로 컨테이너의 원소를 제거해야 한다면 list 컨테이너를 선택하는 것이 좋습니다.

list의 remove_if()

조건자를 이용해 원소를 제거해야 한다면 remove_if() 버전의 멤버 함수를 사용합니다.

remove_if() 멤버함수는 당한 조건자가 참인 모든 원소를 제거합니다. 조건자는 bool 형식을 반환하는 함수류 입니다.

bool Predicate(int n)
{
	return 10 <= n && n <= 30;
}

list<int>::iterator iter;

lt.remove_if(Predicate);

list의 splice()

순서가 있는 노드 기반 컨테이너 list는 이런 특징을 잘 반영하듯 splice()라는 멤버 함수를 가집니다. splice()는 다른 컨테이너의 순차열을 잘라붙일 수 있습니다.

list<int>::iterator iter;

iter = lt1.begin();
++iter;
++iter;

lt1.splice(iter, lt2) // iter가 가리키는 위치에 lt2의 모든 원소를 잘라 붙임
//결과
lt1: 10 20 100 200 300 400 500 30 40 50
lt2: 

splice 동작은 상수 시간의 실행 동작을 보입니다. lt1과 lt2의 노드들을 단지 연결하기 때문입니다.