목록CSE/Algorithm(c++) (9)
dev-miri
트리는 계층적 데이터를 표현하는 좋은 방법이지만, 하나의 노드에서 다른 노드로 이동하는 경로가 하나만 존재하기 때문에 원형 또는 순환적인 종속성을 표현할 수 없다. 그러나 실생활에서 순환 구조를 사용하여 표현해야 하는 시나리오도 많이 존재한다. 예를 들어 도로망을 생각해보면, 특정 장소(노드)에서 다른 장소로 이동하기 위한 다양한 경로가 존재할 수 있다. 이러한 경우에는 그래프(graph) 구조를 사용하는 것이 더욱 바람직하다. 그래프는 노드 데이터뿐만 아니라 노드 사이의 에지 데이터도 저장해야 한다. 도로망을 예로 들면 각각의 노드(장소)에 다른 어떤 노드들이 연결되어 있는지에 대한 정보를 가지고 있어야 한다. 이런 방법으로 필요한 모든 노드와 에지가 있는 그래프를 만들 수 있으며, 이러한 그래프를 비..
서론 이전까지는 다양한 유형의 선형 자료 구조를 구현하여 데이터를 저장하고 관리하는 방법에 대해 알아봤다. 선형 구조에서는 최대 두 가지 방향(순방향과 역방향)으로 자료를 순회할 수 있다. 그러나 이러한 구조는 매우 제한적이어서 복잡한 문제에는 적용하기 어렵다. 그러므로 이전 장에서 배웠던 자료 구조를 확장하여 비선형 데이터를 표현할 수 있는 복잡한 자료 구조를 만들어볼 것이다. 비선형 문제 선형 자료 구조로 표현할 수 없는 대표적인 문제로는 계층적 문제(hierarchical problem)와 순환 종속성(cyclic dependency) 문제가 있다. 계층적 문제 위 그림은 어떤 회사의 조직도이다. 이러한 조직 구성은 계층적으로 표현되며, 이는 배열, 벡터, 연결 리스트 같은 자료 구조로는 표현하기 ..
서론 지금까지 살펴본 컨테이너는 완전히 바닥부터 만들어졌다. 이 절에서는 이미 존재하는 컨테이너를 기반으로 만들어진 컨테이너에 대해 알아보자. 기존 컨테이너를 감싸는 래퍼를 제공하는 데에는 몇 가지 이유가 있다. 코드에 좀 더 의미를 부여하고 싶음 의도하지 않는 함수를 실수로 사용하지 못하도록 제한 특별한 인터페이스를 새롭게 제공하고 싶음. 이러한 자료 구조 중의 하나가 스택(stack)이다. 스택은 데이터 처리와 보관을 위해 LIFO(Last In First Out, 후입선출) 구조를 사용한다. 기능적인 측면에서 스택은 컨테이너 한쪽 끝에서만 데이터를 삽입하거나 삭제할 수 있으며, 한쪽 끝이 아닌 위치에 있는 데이터는 접근하거나 변경할 수 없다. 벡터나 덱은 이러한 기능을 기본적으로 지원하기 때문에 스..
서론 지금까지 배열 기반과 연결 리스트 기반 컨테이너를 살펴봤다. std::deque은 두 가지 방식이 섞여 있는 형태이며, 각각의 장점을 적당히 가지고 있다. 앞서 살펴봤듯이 벡터는 가변 길이 배열이고, push_front() 또는 pop_front() 같은 함수는 비용이 많이 드는 작업이다. (원소 삽입 후 모든 원소를 한 칸씩 뒤로 이동시켜야 하기 때문이다.) std::deque을 사용하면 이런 단점을 극복할 수 있다. deque는 양방향 큐(double-ended queue)의 약자이다. 덱의 구조 C++표준은 덱의 동작에 있어서 다음 조건을 만족해야 한다고 규정한다. push_front(), pop_front(), push_back(), pop_back() 동작이 O(1) 시간 복잡도로 동작해야..
반복자 std::forward_list 반복자와 std::vector, std::array 반복자의 차이를 알아볼 것이다. 앞에서 배열과 포인터를 설명할 때 반복자에 숫자를 더하여 사용한 것을 기억할 것이다. 반복자는 포인터와 비슷하지만, STL 컨테이너에 대해 공통의 인터페이스를 제공한다. 반복자를 이용한 연산은 어떤 컨테이너에서 정의된 반복자인지에 따라 결정된다. 백터와 배열에서 사용하는 반복자는 기능 면에서 가장 유연하다. 백터와 배열은 연속된 자료구조를 사용하기 때문에 특정 위치의 원소에 곧바로 접근할 수 있다. 이러한 반복자를 임의 접근 반복자(random access iterator)라고 한다. 그러나 std::forward_list의 경우 기본적으로 역방향으로 이동하는 기능을 제공하지 않으며..
서론 지금까지 살펴본 배열, 벡터 같은 연속된 자료 구조에서는 데이터 중간에 자료를 추가하건 삭제하는 작업이 매우 비효율적이다. 그래서 연결 리스트와 같은 형태의 자료 구조가 등장한다. 많은 응용 프로그램에서는 자료 구조 중간에 삽입 도는 삭제 작업을 필요로 하기 때문이다. 기본적으로 연결 리스트를 구성하려면 포인터를 하나 가지고 있어야 하고, new와 delete 연산자를 이용하여 메모리를 할당하고 해제할 수 있어야 한다. 이러한 기능을 구현하는 것이 그리 어렵진 않지만 자칫 잘못하면 찾기 어려운 버그를 양산할 수 있기 때문에, C++에서는 C 스타일 배열에 대한 래퍼 클래스 std::array를 제공하듯이 기본적인 연결 리스트에 대한 래퍼 클래스인 std::forward_list 클래스를 제공한다. ..