Stack, Queue, Deque
- OS ๋ด๋ถ ๋ง์ ์์คํฌ์ด ์คํ๊ณผ ํ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ค.
- ์ดํ ์ฅ์์ ๋ฐฐ์ธ ๋ด์ฉ์ธ ํธ๋ฆฌ ์ํ๋ ์คํ๊ณผ ํ๋ก ํ๊ฒ ๋๋ค.
- 1์ฅ์์ ๋ฐฐ์ด ์คํ ํ๋ ์๋ ์คํ์ด๋ค.
- ์คํ ํ๋ ์ : ํจ์๊ฐ ํธ์ถ๋ ๋ ๋ฉ๋ชจ๋ฆฌ์์ ์๊ธด ๊ณต๊ฐ
[ ๊ฐ๋ ์ค๋ช ]
1. Stack : ์ ์ ์๊ธฐ
- ์๋ก ๋ค์ด์ค๋ ์ ์๋ ์ธ์ ๋ ๊ฐ์ฅ ์์ ์์ธ๋ค (IN)
- ์ฌ์ฉํ๊ธฐ ์ํด ๋๊ฐ๋ ์ ์๋ ์ธ์ ๋ ๊ฐ์ฅ ์์์ ๋๊ฐ๋ค (OUT)
- LIFO(Last In First Out)
2. Queue : ์ค์๊ธฐ
- ์๋ก ์ค์๋ ์ฌ๋์ ์ธ์ ๊ฐ ๊ฐ์ฅ ๋ง์ง๋ง์ ์ค์ ์ ๋ค (IN)
- ์ค์์ ๊ฐ์ฅ ์ฒซ๋ฒ์งธ ์ฌ๋์ด ๊ฐ์ฅ ๋จผ์ ๋๊ฐ๋ค (OUT)
- FIFO(First In Fist Out)
3. Deque : Stack ๊ธฐ๋ฅ + Queue ๊ธฐ๋ฅ
- Stack๊ณผ Queue๋ In & Out ๋ฐฉํฅ์ด ์ค๋ก์ง ํ๋
3-1. Stack
- Stack(์ ์ ์๊ธฐ)๋ top(์)์์ IN
- Stack(์ ์ ์๊ธฐ)๋ top(์)์์ OUT
- Deque์ ๊ฐ์ฅ ์๋(bottom)์์ IN & OUT ๊ฐ๋ฅ
3- 2. Queue
- Queue(์ค์๊ธฐ)๋ raer(๊ฐ์ฅ ๋ง์ง๋ง)์์ IN
- Queue(์ค์๊ธฐ)๋ front(๊ฐ์ฅ ์ฒซ๋ฒ์งธ)์์ OUT
- Deque์ rear, front ๋ ๋ค IN & OUT ๊ฐ๋ฅ
[ ๊ตฌํ ]
1. Stack : ์ ์ ์๊ธฐ
Operation (์ฐ์ฐ)
class Stack:
def __init__(self):
self.container = list() # ๋ด๋ถ ํํ(representation): ์ค์ ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ด๋ ๊ฐ์ฒด๋ ๋์ ๋ฐฐ์ด
def empty(self):
if not self.container:
return True
else:
return False
def push(self, data):
self.container.append(data)
def pop(self):
if self.empty():
return None
return self.container.pop()
def peek(self):
if self.empty():
return None
return self.container[-1]
s = Stack()
s.push(1)
s.push(2)
s.push(3)
while not s.empty(): ## stack์ด ๋น์ด์์ง ์์ผ๋ฉด ๋ง์ง๋ง ๊ฐ์ ์ถ๋ ฅํ๋ผ
print(s.pop(), end=" ")
3 2 1
๊ทธ๋ฅ list ์ฐ๋ฉด ๋์ง ์๋์?
- ๋ด๋ถ ํํ์ python์ ๋์ ๋ฐฐ์ด์ธ list๋ก ํ์ง๋ง, ๋ฆฌ์คํธ ํจ์๋ฅผ wrapping(๋ํ)ํ์ฌ ์ถ์ํ ์ํด
- ํ๋ก๊ทธ๋๋จธ์๊ฒ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๊ธฐ ๋๋ฌธ์
- ์ด๊ฒ ๋์ ๋ฐฐ์ด์ธ์ง, ์คํ์ธ์ง๋ฅผ ์ฐพ๊ธฐ ์ํด ์ฝ๋๋ฅผ ๊ผผ๊ผผํ๊ฒ ๋ถ์ํด์ผํ๋ค๊ณ ํฉ๋๋ค.
- ๋์ํ์๋์?
2. Queue : ์ค์๊ธฐ
Operation (์ฐ์ฐ)
class Queue:
def __init__(self):
self.container = list()
def empty(self):
if not self.container:
return True
else:
return False
def enqueue(self, data):
self.container.append(data)
def dequeue(self):
# ๋์ ๋ฐฐ์ด์ ๋งจ ์ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๋ฏ๋ก ๋น
์ค๋ O(n)
# ์ข ๋ ํจ์จ์ ์ผ๋ก ๊ตฌํํ ์๋ ์์๊น?
return self.container.pop(0)
def peek(self):
return self.container[0]
class CQueue:
MAXSIZE = 10
def __init__(self):
self.container = [None for _ in range(CQueue.MAXSIZE)] ## MAXSIZE ๊ฐ์์ None ์์๊ฐ ๋ด๊ธด LIST
self.front = 0
self.rear = 0 # ์ํ ํ์ ๋ด๋ถ ํํ์ ๋์ ๋ฐฐ์ด์ธ ๋ฆฌ์คํธ.
# front์ reear๋ฅผ 0์ผ๋ก ์ด๊ธฐํ
# ๋๊ฐ ๊ฐ์ด ๊ฐ๊ธฐ ๋๋ฌธ์ ํ๊ฐ ๋น์ด์์
def is_empty(self):
if self.front == self.rear:
return True
return False
def __step_forward(self, x): ## ํธ์ํจ์: front๋ rear๋ฅผ ๋ค๋ก ์ด๋ํ์ ๋ ๋์ ๋ฐฐ์ด์ ๋ฒ์ด๋๋ค๋ฉด ๋์ ๋ฐฐ์ด์ ๋งจ ์ฒ์์ผ๋ก ์ด๋
x += 1 # ๊ทธ ๋ค์ ํฌ์ธํธ๋ฅผ ์ฐพ๊ธฐ์ํด์ +1
if x >= CQueue.MAXSIZE:
x = 0
return x
# front์ rear๊ฐ ์ด๋ํ ๋(enqueue : rear ์ด๋, dequeue : front ์ด๋) ๋ฌด์์ 1์ ๋ํ ์ ์๊ธฐ ๋๋ฌธ์
# ๋์ ๋ฐฐ์ด์ ๋์ ๋๋ฌํ๋ฉด ๋งจ ์ฒ์์ผ๋ก ์ด๋ํ๊ฒ ๋ง๋ค์ด์ค (์ฆ 1์ ๋ํ๋ฉด์ ์ํ์ผ๋ก ์ฐ๊ฒฐ ์์ผ์ค)
def is_full(self):
next = self.__step_forward(self.rear) # ๊ทธ๋ฅ ๋จ์ํ rear+1์ ํ๋ฉด ํ ์ฌ์ด์ฆ ๋ฒ์ด๋๋ฉด์ ๋ฉ์ด์ง๊ธฐ๋ง ํจ ๊ทธ๋์ __step_forward() ๋ฉ์๋๋ก +1์นธ ์ด๋
if next == self.front:
return True
return False
def enqueue(self, data):
if self.is_full():
raise Exception("The queue is full")
self.container[self.rear] = data # ํ์ฌ ๋ง์ง๋ง ๋ค์(rear) ๋ฐ์ดํฐ๋ก ์
๋ ฅ
self.rear = self.__step_forward(self.rear) # ๋ฐ์ดํฐ๊ฐ ํ๋ ๋ค์ด์์ rear ์์๋ก ๋ค์ด๊ฐ๊ฒ ๋๋ฉด rear๋ +1 (์์ผ๋ก ์ ์ง) ํด์ค์ผํจ.
# rear๋ ๋งจ ๋ง์ง๋ง ๋ฐ์ดํฐ๊ฐ ์๋ ๋งจ ๋ง์ง๋ง ๋ฐ์ดํฐ์ ๋ค์์ ๊ฐ๋ฆฌํค๊ณ ์๊ธฐ ๋๋ฌธ์
def dequeue(self):
if self.is_empty():
raise Exception("The queue is empty")
ret = self.container[self.front] # ๊ฐ์ฅ ์(front)์ ์์๋ฅผ ret์ผ๋ก ํ ๋น
self.front = self.__step_forward(self.front)
return ret
# ์ฒซ๋ฒ์งธ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๋ค๊ณ ํด์ ๋ฐ๋ก front๋ฅผ ๋ค๋ก ์ด๋์์ผ์ ์๋จ.
# ๋ฐ์ดํฐ๋ฅผ ๋ฐํํด์ผํ๊ธฐ ๋๋ฌธ์ ๋จผ์ ret ๋ณ์์ ์ญ์ ๋ ์์๋ฅผ ๋ด์ ํ ์ญ์ ํ๊ณ front๋ฅผ ๋ค๋ก ์ด๋์ํค๊ณ ret ๊ฐ์ ๋ฐํ ํด์ผํจ
# (๋ฐ๋ก ์ญ์ ์ํด๋๋๋๊ฒ ์ด์ฐจํผ rear๊ฐ ์ฒซ ์์์ ํ ๋น๋์ด ์์ด๋ enqueue ๋๋ ๋ค๋ฅธ ๊ฐ์ผ๋ก ๋ฐ๋๊ฑฐ๋ผ)
def peek(self):
if self.is_empty():
raise Exception("The queue is empty")
return self.container[self.front]
cq = CQueue()
for i in range(8):
cq.enqueue(i) # 0๋ถํฐ 7๊น์ง ๊ฐ ์ฝ์
for i in range(5):
print(cq.dequeue(), end=" ") # 5๊ฐ ์๋ถ๋ถ ์ญ์ (0๋ถํฐ 4๊น์ง ๋ ๋ฆผ. 5๋ถํฐ 7๊น์ง๋ง ์กด์ฌํ์ง๋ง ๊ฐ์ ๊ทธ๋๋ก)
for i in range(8,13): ## 8๋ถํฐ 13๊น์ง 6๊ฐ ์ฝ์
ํ์ง๋ง 5๊ฐ ์๋ถ๋ถ์ด ๋ ๋ผ๊ฐ๊ธฐ ๋๋ฌธ์ ์์ฐ์ค๋ฝ๊ฒ ์ด์ด์ง (10,11,12,13,4,5,6,7,8,9,) ## ๋ง์ฝ์ 18๊น์ง ํ๋ค๋ฉด Exception ์๋ฌ ๋ธ
cq.enqueue(i)
print()
while not cq.is_empty(): # container๊ฐ ๋น์ด์์ง ์๋ค๋ฉด ๊ณ์ ์ํ
print(cq.dequeue(), end=" ") ## 5๋ฒ๋ถํฐ 13๊น์ง ์ญ์
print()
for i in range(10):
print(cq.container[i], end=" ") ## ์ค์ ๋ด๋ถ์ ์๋ ๋์ ๋ฐฐ์ด์ ์ค์ ๋ชจ์ต
0 1 2 3 4
5 6 7 8 9 10 11 12
10 11 12 3 4 5 6 7 8 9
## SAMPLE ###
print()
print(cq.peek())
Exception: The queue is empty
3. Deque
Operation (์ฐ์ฐ)
from collections import deque
print('*' * 20 + ' STACK ' + '*' * 20)
stack = deque()
for i in range(1,6): # 1๋ถํฐ 5๊น์ง
stack.append(i) # ๋ค์ ์
๋ ฅ (rear์ ๋ฐ์ดํฐ ์
๋ ฅ)
print(stack)
for i in range(5):
print(stack.pop()) # ๋ค์์ ์ถ๋ ฅ ๋ฐ ์ญ์ (rear์ ๋ฐ์ดํฐ ์ถ๋ ฅ)
print('*' * 20 + ' QUEUE ' + '*' * 20)
queue = deque()
for i in range(1,6):
queue.append(i)
print(queue)
for i in range(5):
print(queue.popleft()) # ์์์ ์ถ๋ ฅ ๋ฐ ์ญ์ (front์ ๋ฐ์ดํฐ ์ถ๋ ฅ) //// ์ฐธ๊ณ ๋ก ์๋ถ๋ถ์ ๋ฐ์ดํฐ ์
๋ ฅ์ ํ๊ธฐ ์ํด์ appendleft()
******************** STACK ********************
deque([1])
deque([1, 2])
deque([1, 2, 3])
deque([1, 2, 3, 4])
deque([1, 2, 3, 4, 5])
5
4
3
2
1
******************** QUEUE ********************
deque([1])
deque([1, 2])
deque([1, 2, 3])
deque([1, 2, 3, 4])
deque([1, 2, 3, 4, 5])
1
2
3
4
5
[ ์ฌ์ฉ ์ฌ๋ก ]
1. Stack : ์ ์ ์๊ธฐ
- ์๊ฒ ๋ชจ๋ฅด๊ฒ ๋ค์ํ ๊ณณ์ ์ฐ์ด๊ณ ์๋ค.
- ์คํ ํ๋ ์ (ํจ์๊ฐ ํธ์ถ๋ ๋ ๋ฉ๋ชจ๋ฆฌ์์ ์๊ธด ๊ณต๊ฐ)
2. Queue : ์ค์๊ธฐ
- ์คํ๋ณด๋ค ๋ ๋ค์ํ ๊ณณ์์ ์ฌ์ฉ๋๋ค
- OS๋ task queue๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ผ์ค๋งํ๋ค
- ์ค์ผ์ค๋ง์ด๋
- ์ปดํจํฐ๋ ๋์์ ์ฌ๋ฌ ํ๋ก๊ทธ๋จ์ ์คํํ ์ ์๋๋ฐ ์ค์ ๋ก ์์ ์ ์ํํ๋ CPU ๊ฐ์๋ ์ ํ์ ์
- ์ด๋ OS๋ ์ฌ๋ฌ ํ๋ก๊ทธ๋จ์์ ์์ ์ ์์ฒญ๋ฐ์ ์ด๋ฅผ ํ์ ๋ด์ ํ, ์ ํด์ง ์๊ณ ๋ฆฌ์ฆ์ ๋ฐ๋ผ ํ์์ ํ ์คํฌ(์์ )๋ฅผ ์คํํจ
- ์ด๋ ๊ฒ ์คํํ ์์ ์์๋ฅผ ์ ํ๋ ๊ฒ์ ์ค์ผ์ค๋ง์ด๋ผ ํ๋ค.
- ์ค์ผ์ค๋ง์ด๋
3. Deque : Stack ๊ธฐ๋ฅ + Queue ๊ธฐ๋ฅ
- Deque๋ฅผ ์ฌ์ฉํ์ฌ stack๊ณผ queue๋ฅผ ๊ตฌํํ๋ค (ํ๋ด๋ธ๋ค)