혼자 정리
[CLSR] 10.1 Stacks and queues (Ch.10 Elementary Data Structures) 본문
[CLSR] 10.1 Stacks and queues (Ch.10 Elementary Data Structures)
tbonelee 2021. 4. 6. 23:58스택과 큐는 제거 행위로 집합에서 제거될 원소가 미리 명시된 동적 집합의 일종이다.
스택은 후입선출(last-in, first-out; LIFO).
큐는 선입선출(first-in, first-out; FIFO).
구현에 다양한 방법이 있지만 여기서는 배열을 통한 구현을 다룬다.
Stacks
스택의 'Insert' 행위는 'Push'라 부르고 'Delete'행위는 'Pop'이라 부른다.
최대 $n$개의 원소를 가진 스택을 배열 $S[1 \cdots n]$으로 구현할 수 있다.
'$S.top$'은 가장 최근에 삽입된 원소의 배열에서의 인덱스를 나타내느 $S$의 속성(attribute)이다.
즉, 스택은 원소 $S[1 \cdots S.top]$을 가지고 있고, $S[1]$은 스택 최하단에, $S[S.top]$은 스택 최상단에 위치한다.
$S.top = 0$이면 스택에 원소가 없고 비어있는(empty) 상태로 본다.
'$Stack-Empty$'라는 쿼리 연산을 통해 스택이 비어있는지 확인할 수 있다.
빈 스택을 pop하려는 경우 stack underflow라 하고 에러 처리한다.
$S.top$이 $n$을 초과하는 경우 stack overflow라 한다.
스택과 관련된 연산들을 다음의 수도 코드로 나타낼 수 있다.(오버플로우 고려하지 않음)
- $Stack-Empty(S)$
if S.top == 0
return TRUE
else
return FALSE
- $PUSH(S, x)$
S.top = S.top + 1
S[S.top] = x
- $Pop(S)$
if Stack-Empty(S)
error "underflow"
else S.top = S.top - 1
return S[S.top + 1]
위 그림에서는 Push와 Pop 연산을 보여준다. 각 연산은 $O(1)$이 걸린다.
Queues
큐에서는 'Insert'연산을 '$Enqueue$'라 하고 'Delete'연산을 '$Dequeue$'라 한다.
큐의 FIFO 특성은 은행에서 대기표를 받고 기다리는 손님들과 비슷한 방식으로 비유할 수 있다.
큐는 head와 tail을 갖는다.
원소가 enqued되면 줄 선 손님처럼 tail로 자리 잡는다.
원소가 dequed되면 맨 앞의 손님처럼 head의 원소가 dequed된다.
최대 $n-1$개의 원소를 갖는 큐는 배열 $Q[1 \cdots n]$을 통해 구현할 수 있다.
$Q.head$는 head를 가리키는 인덱스이고 $Q.tail$은 tail을 가리키는 인덱스이다.
tail은 다음 원소가 들어오게 될 위치를 가리키고 있다.
큐의 원소는 $Q.head$, $Q.head + 1$, ... , $Q.tail - 1$에 위치하고 순환하는 형태로 위치가 이어진다.
$Q.head = Q.tail$인 경우 큐가 비어있는 상태이다. 초기에는 $Q.head = Q.tail = 1$이다.
빈 큐에서 dequeue하는 경우 queue underflow이다.
$Q.head = Q.tail + 1$인 경우 큐는 꽉 찬 상태이다. 꽉 찬 큐에 enqueue 하는 경우 queue overflow이다.
다음은 큐의 각 연산들에 대한 수도코드이다(오버플로우, 언더플로우 고려하지 않음).
각 연산들은 $O(1)$이 걸린다.
- $Enqueue(Q, x)$
Q[Q.tail] = x
if Q.tail == Q.length
Q.tail = 1
else Q.tail = Q.tail + 1
- $Dequeue(Q)$
x = Q[Q.head]
if Q.head == Q.length
Q.head = 1
else Q.head = Q.head + 1
return x