STL containers
std::array
C-style array랑 다른 점
- 자동 메모리 할당 / 해제
- 자동 에러 탐지
- out of range 에러 등등
- Deep copy 기능 추가
- 자동으로 deep copy를 사용함.
- 복사 작업을 피하고 싶다면, reference나 const를 이용해서 추가하면 됨.
사용 예제
1 | // Init |
std::vector
std::array랑 다른 점
std::array
의 고정된 크기랑은 다르게 dynamic한 크기를 가짐.
특징
- 새로운 데이터 원소를 채워넣는데에는
만큼 소요. size
와capacity
를 가지고 있음.- size는 실제로 데이터가 채워진 메모리의 양.
- capacity는 현재 vector에 할당된 메모리의 양.
- capacity가 다 차게 되면, 2*size만큼 새로 capacity를 할당.
- 새로 할당된 메모리로 기존의 정보를 모두 이동 (i.e. 복사 이동)
- 이 경우,
만큼 소요.
insert()
는만큼 소요.
사용 예제
1 | std::vector<int> vec; // 빈 vector |
std::forward_list
Contiguous data structure의 단점
- 데이터 중간에 자료를 추가하거나 뺄 때 비효율적.
std::forward_list 특징
- Linked list 자료구조에 간편한 기능들을 추가한 클래스.
- 최앞단 원소만 바로 접근 가능.
push_front()
또는insert_after()
을 사용해서으로 추가 가능.
remove(x)
를 통해 list 내부에 x라는 값을 가진 원소를 모두 없앰.- list 내부에 있는 데이터들이
==operator
가 안된다면 컴파일러 에러.
- list 내부에 있는 데이터들이
remove_if(comp)
를 사용해서 list 내부에 comp 함수의 조건을 맞춘 원소를 모두 없앰.- 람다 함수를 이용해서 만들면 좋음.
remove()
와remove_if()
는 전체를 순회하기 때문에이 걸림. sort()
를 쓸 수 있지만,std::vector
등에서 쓰는 sort와 다름.<operator
를 통해 사용하거나 커스텀 cmp 함수를 통해 사용 가능.만큼 소요됨.
reverse()
로 순서를 뒤집을 수 있음.
사용 예제
1 |
|
std::list
구현 방법
- Doubly-linked list
- 각 node가 이전 node와 다음 node에 대한 포인터 값을 가지고 있음.
std::forward_list
가 지원하지 못하는push_back()
,emplace_back()
,pop_back()
을 할 수 있음.으로 작동함.
- 기존의
remove()
,remove_if()
,sort()
,unique()
,reverse()
등도 사용할 수 있음.- 훨씬 편리하기 때문에 대부분의 경우
std::forward_list
보다std::list
를 더 많이 사용함.
- 훨씬 편리하기 때문에 대부분의 경우
- Bidirectional iterator 사용.
사용 예제
1 | std::list<int> lst = {1,2,3,4,5}; |
Iterators (simple)
구현
이미지 출처
Iterator의 종류는 사용하는 컨테이너에 따라 결정된다.
std::vector
,std::array
는 contiguous data structure이기 때문에 특정 위치의 데이터 원소에 곧바로 접근 가능.- Random access iterator
std::forward_list
는 역방향이 존재하지 않음.- Forward iterator
std::list
는 양방향 움직일 수 있음.- Bidirectional iterator
advance()
,next()
,prev()
로 움직일 수 있음.
1 |
|
std::deque
구현
- Deque: Double-ended queue 의 약자.
- 성능:
push_front()
,pop_front()
,push_back()
,pop_back()
이 모두작동. - Random access도
작동. insert()
와delete()
는작동.
- 메모리 구조:
- 크기가 같은 여러개의 메모리 청크를 사용.
- 이 메모리 청크들의 주소를 연속적인 메모리 구조에 저장.
- 새로운 메모리 공간을 할당할 때, 기존의 메모리는 그대로 있음.
- 지원 함수:
push_front()
,pop_front()
,emplace_front()
push_back()
,pop_back()
,emplace_back()
insert()
,emplace()
,delete()
erase()
shrink_to_fit()
capacity()
는 지원 안됨!
std::vector
와는 메모리 할당 방식이 다름.
사용 예제
1 | std::deque<int> deq = {1,2,3,4,5}; |
std::stack (container adapter)
구현
std::deque
를 기본 컨테이너로 사용하여 만든 래퍼 클래스.- 원소 저장 공간을 재할당할때
std::vector
처럼 전체 원소를 이동할 필요가 없기 때문. - 하지만 원한다면
std::stack<int, std::vector<int>>
와 같은 형태로 만들 수 있음. std::stack<int, std::list<int>>
도 가능.
- 원소 저장 공간을 재할당할때
- LIFO (Last In First Out) 구조를 가지고 있음.
std::deque
는 push_front()를 지원…std::stack
은 해당 기능을 꺼둠. 왜냐하면 stack은 push_front같은거 지원하지 않기 때문.
- 모든 연산의 시간 복잡도가
std::queue (container adapter)
구현
- FIFO (First In First Out) 구조
std::queue
에서의push()
는std::stack
에서의push_back()
을 의미std::queue
에서의pop()
는std::stack
에서의pop_front()
를 의미
- 기본적으로
std::deque
를 사용해서 만든 래퍼 클래스.- 모든 함수가
으로 사용 가능.
- 모든 함수가
사용 예제
1 | std::queue<int> q; |
std::priority_queue
구현
- Priority queue, 또는 Heap이라고도 불림.
- 가장 작거나 (또는 가장 큰) 원소에 빠르게 접근 할 수 있는 자료구조.
- 최소/최대 원소에 접근하는데는
- 원소 삽입/제거는
- 원소 제거는 최소/최대 원소에 대해서만 가능.
std::vector
를 기본 컨테이너로 사용해서 구현.- 기본적으로
std::less
를 사용해서 max heap이 구현되어있음
사용 예제
1 | // Creates a max heap |