오늘은 선형 자료구조에 해당하는 자료구조 중 대표적인 스택, 큐, 덱 3가지의 자료구조에 대해서 알아보겠습니다.
스택은 가장 마지막에 저장된 데이터가 가장 먼저 삭제되는 후입선출(LIFO, Last In First Out) 구조입니다.
스택은 한쪽 방향에서만 데이터의 삽입과 삭제가 가능합니다.
스택 용어
사용되는 예
스택의 자료구조는 삽입과 삭제시에 O(1), 탐색에는 O(n)의 시간복잡도를 가지게 됩니다.
큐는 위에서 설명한 스택과는 달리 한 쪽에서는 데이터 삽입, 다른 한 쪽에서는 데이터의 삭제만 가능한 선입선출(FIFO, First In First Out) 구조를 가지고 있습니다.
실생활에서는 재료의 선입선출(유통기한이 오래된 것을 가장 앞쪽에 배치), 식당의 줄서기 등이 대표적인 예입니다.
큐 용어
사용되는 예
큐에는 우선순위 큐, 원형 큐라는 2개의 종류가 더 있기 때문에 지금 설명하는 큐는 선형 큐(Linear Queue)라고도 부릅니다.
큐는 스택과 마찬가지로 삽입과 삭제에는 O(1), 탐색에는 O(n)의 시간복잡도를 가집니다.
우선순위 큐의 각 요소는 값과 우선순위, 총 2개의 데이터를 가지고 있습니다.
따라서 선형큐와는 달리 우선순위가 높은 요소일수록 먼저 삭제되는 특징을 가지고 있으며 우선순위가 같은 데이터일 경우 삽입순서를 따릅니다.
삽입 및 삭제 시 우선순위에 따라 요소들을 정렬 해야하기 때문에 주로 힙(Heap)이라는 자료구조로 구현되며
실생활에서 병원의 응급실에서는 응급 환자가 우선 순위가 높으므로 먼저 진료를 받고 일반 환자는 순서가 뒤로 밀리는것과 같은 맥락입니다.
우선순위 큐는 어떻게 구현하느냐에 따라 시간복잡도가 달라지지만 힙을 기준으로 한다면 삽입과 삭제에는 O(logn), 우선순위가 가장 높은 요소를 탐색할 때는 O(1)만큼의 시간복잡도를 가집니다.
원형 큐는 선형 큐의 단점을 보완하기 위해 나왔습니다.
큐는 사이즈가 고정되어있고 데이터의 삽입과 삭제시 나머지 요소들은 이동하지 않습니다.
따라서 데이터의 삽입과 삭제가 반복되면 언젠가 Rear는 큐의 마지막 인덱스를 가르키게 되고 이전에 삭제 작업을 진행하여 앞에 빈 공간이 있더라도 활용하지 못하게 됩니다.
따라서 선형 큐는 빈 공간을 활용하기 위해 현재 요소들을 앞으로 재배치하는 별도의 작업이 필요합니다.
하지만 원형큐의 경우 Front와 Rear가 아래 그림처럼 순환하기 때문에 빈 공간을 사용하기 위한 별도의 작업이 필요하지 않습니다.
위의 사진에서 Front와 Rear의 움직임을 보면 Front와 Rear가 계속해서 돌고 있는 모습을 볼 수 있습니다.
이러한 움직임을 만들어내기 위해서 원형 큐에서는 Enqueue 및 Dequeue시에 아래와 같은 작업을 합니다.
function enqueue() {
// ...
rear = (rear + 1) % queue_size;
}
function dequeue() {
// ...
front = (front + 1) % queue_size;
}
예를 들어, 큐의 전체 사이즈가 5이고 현재 Rear가 마지막 인덱스인 4를 가르키고 있다고 가정해보겠습니다.
여기서 Enqueue를 하게되면 Rear의 인덱스는 5가 될텐데 여기에 큐의 전체사이즈를 나눈 나머지를 구합니다.
5 % 5 = 0
이므로 이 값을 Rear에 할당하여 인덱스가 다시 0을 가르킬 수 있도록 합니다.
이렇게 하면 정렬과정 없이 Front와 Rear가 순환하는 형태를 만들 수 있습니다.
덱은 큐 2개를 겹쳐놓은것과 같기 때문에 Double ended Queue라고 부르며 Deque이라는 명칭은 이를 축약형으로 부르는 것입니다.
이 자료구조는 이름처럼 양쪽에서 데이터의 입, 출력이 모두 가능한 자료구조입니다.
JS에서는 배열의 내장메소드로 모두 구현되어있으며
스택, 큐와 마찬가지로 front와 rear라는 포인터가 있으며 이들은 각각 가장 앞, 뒤에 있는 데이터를 가르킵니다.
다만, 스택과 큐의 Rear는 다음 요소가 삽입 될 위치를 가르키는 반면
덱의 Rear는 마지막 요소를 가르키고 있게 됩니다.
스택, 큐와 같이 데이터의 삽입과 삭제에 O(1)의 시간복잡도를 가집니다.
정말 가독성 좋고 알기 쉽게 설명해주셨네요 감사합니다 잘 읽고 갑니다~!