std::list는 양방향 연결 리스트입니다.push_front, push_back)은 O(1)입니다.reserve/capacity 개념이 없습니다.vector vs list 핵심 비교| 항목 | vector | list |
|---|---|---|
| 메모리 구조 | 연속 메모리 | 노드 연결 |
임의 접근 v[i] | O(1) | 미지원 (O(N) 이동 필요) |
| 중간 삽입/삭제 | O(N) (원소 이동) | 위치를 알고 있으면 O(1) |
| 캐시 친화성 | 매우 좋음 | 상대적으로 불리 |
| 이터레이터 안정성 | 재할당/중간 수정에 취약 | 삭제된 원소 외 대체로 안정적 |
vector vs list 구조 비교
[ vector ] 연속 메모리, 인덱스 O(1) 접근
┌───┬───┬───┬───┬───┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ v[2] → 바로 접근
└───┴───┴───┴───┴───┘
[ list ] 노드 연결, N번째 접근 O(N)
head → [10]↔[20]↔[30]↔[40]↔[50] → tail
3번째 접근 = next 3번 따라가야 함
| 연산 | 복잡도 | 비고 |
|---|---|---|
push_front, push_back | O(1) | 앞/뒤 삽입 |
insert(it), erase(it) | O(1) | 해당 위치(it)를 이미 알고 있을 때 |
find, count | O(N) | 순차 탐색 |
sort() (멤버 함수) | O(N log N) | list 전용 정렬 |
| N번째 접근 | O(N) | operator[] 미지원 |
list<int> lst{4, 1, 3, 2};
// std::sort(lst.begin(), lst.end()); // X: RandomAccessIterator 필요
lst.sort(); // O(N log N), list 전용 멤버 정렬
// binary_search는 사용 가능하지만(list 이터레이터는 bidirectional)
// 이동 비용 때문에 실무 이점이 작습니다.
bool ok = binary_search(lst.begin(), lst.end(), 3); // 정렬되어 있다는 가정 필요
list는 std::sort가 아니라 list::sort()를 사용해야 합니다.vector + sort + binary_search 조합이 더 유리합니다.splice: 노드를 다른 리스트로 복사 없이 이동merge: 정렬된 두 리스트 병합unique: 연속 중복 제거remove, remove_if: 조건 기반 삭제list<int> a{1, 2, 3};
list<int> b{10, 20};
auto it = a.begin();
++it; // 2
b.splice(b.end(), a, it); // a의 2를 b 끝으로 이동
list를 선택할까?list가 유리한 경우:
vector가 유리한 경우:
vector를 우선 고려list ≈ C# LinkedListvector ≈ C# Listlist에서 중간 삽입이 빠른데도 기본 컨테이너가 보통 vector인 이유는?list 정렬에 std::sort가 아닌 list::sort()를 써야 하는 이유는?insert/erase가 O(1)이라는 뜻을 설명할 수 있는가?