Queue ํ ๋?
queue๋ ์ ์ ์ ์ถ FIFO(First In Frist Out)์ ์๋ฃ๊ตฌ์กฐ์ด๋ค ์๊ฐ๋ณต์ก๋๋ enqueue O(1), dequeue O(1) ์ ๋๋ค.
ํ์ฉ ์์ Cache ๊ตฌํ, ํ๋ก์ธ์ค ๊ด๋ฆฌ, ๋๋น์ฐ์ ํ์(BFS) ๋ฑ์ด ์์ต๋๋ค.
FIFO (First In First Out) ์ด๋?
queue๋ ์๊ฐ ์์์ ๋จผ์ ์ง์ด ๋ฃ์ ๋ฐ์ดํฐ๊ฐ ๋จผ์ ๋์ค๋ ์ ์ ์ ์ถ FIFO(First In First Out) ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
enqueue & dequeue
queue์์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ enqueue๋ผ๊ณ ํ๋ค.
queue์์ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ๊ฒ์ dequeue๋ผ๊ณ ํ๋ค.
enqueue์ ๊ฒฝ์ฐ queue์ ๋งจ๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ฉด ์๋ฃ๋๊ธฐ ๋๋ฌธ์ ์๊ฐ๋ณต์ก๋๋ O(1)์ด๋ค.
dequeue์ ๊ฒฝ์ฐ ๋งจ ์์ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๋ฉด ์๋ฃ๋๊ธฐ ๋๋ฌธ์ ๋์ผํ๊ฒ O(1)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ๋๋ค.
๊ตฌํ ๋ฐฉ์
- Array-Based queue: enqueue์ dequeue ๊ณผ์ ์์ ๋จ๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์๊ธด๋ค. ๋ฐ๋ผ์ ๋ฉ๋ชจ๋ฆฌ์ ๋ญ๋น๋ฅผ ์ค์ด๊ธฐ ์ํด ์ฃผ๋ก Circular queueํ์์ผ๋ก ๊ตฌํํ๋ค.
- List-Based: ์ฌํ ๋น์ด๋ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น์ ๊ฑฑ์ ์ ํ ํ์๊ฐ ์์ด์ง๋ค.
์ํํ (circular queue)
queue์ ๊ฐ๋ ์์ ์กฐ๊ธ ํ์ฅํ ์๋ฃ๊ตฌ์กฐ๋ค๋ก๋ ์์ชฝ์์ enqueue์ dequeue๊ฐ ๊ฐ๋ฅํ deque(double-ended queue)์ ์๊ฐ ์์๊ฐ ์๋ ์ฐ์ ์์๊ฐ ๋์ ์์๋ก dequeueํ ์ ์๋ priority queue๊ฐ ์๋ค.
ํ์ฉ ์์๋ก๋ ํ๋์ ์์์ ๊ณต์ ํ๋ ํ๋ฆฐํฐ๋, CPU task scheduling, Cache ๊ตฌํ, ๋๋น์ฐ์ ํ์(BFS) ๋ฑ์ด ์๋ค.
Array-Base์ List-Base ์ฐจ์ด
Array-Base | queue๋ circular queue๋ก ๊ตฌํํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค. ์ด๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ ์ํจ์ด๋ค. ๋ํ, enqueue๊ฐ ๊ณ์ ๋ฐ์ํ๋ฉด fixed size๋ฅผ ๋์ด์๊ฒ ๋๊ธฐ ๋๋ฌธ์, dynamic array์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก Array์ size๋ฅผ ํ์ฅ์์ผ์ผ ํ๋ค. ๊ทธ๋ผ์๋ enqueue์ ์๊ฐ๋ณต์ก๋๋ (amortized) O(1)๋ฅผ ์ ์งํ ์ ์๋ค. |
List-Base | singly-lilnked list๋ก ๊ตฌํํ๋ค. enqueue๋ ๋จ์ํ singly-lilnked์์ append๋ฅผ ํ๋ ๊ฒ์ผ๋ก ๊ตฌํ๋๊ณ , ์ด ๋ ์๊ฐ๋ณต์ก๋๋ O(1)์ด๋ค. dequeue๋ ๋งจ ์์ ์์๋ฅผ ์ญ์ ํ๊ณ first head๋ฅผ ๋ณ๊ฒฝํ๋ฉด ๋๊ธฐ ๋๋ฌธ์์ด ์ฐ์ฐ๋ O(1)์ ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค. |
์์ฝํ์๋ฉด, ๋ ๊ฐ์ง ์ข ๋ฅ์ ์๋ฃ๊ตฌ์กฐ๋ก queue๋ฅผ ๊ตฌํ์ ํ๋๋ผ๋ enqueue์ dequeue๋ ๋ชจ๋ O(1)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ๋๋ค.
Array-Base์ ๊ฒฝ์ฐ ์ ๋ฐ์ ์ผ๋ก performance๊ฐ ๋ ์ข์ง๋ง, worst case์ ๊ฒฝ์ฐ์๋ ํจ์ฌ ๋ ๋๋ฆด ์ ์๋ค(resize).
List-Base์ ๊ฒฝ์ฐ์๋ enqueue๋ฅผ ํ ๋๋ง๋ค memory allocation์ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ ๋ฐ์ ์ธ runtime์ด ๋๋ฆด ์ ์๋ค.
Stack ์คํ ์ด๋?
stack์ ํ์ ์ ์ถ LIFO(Last In First Out)์ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
์๊ฐ๋ณต์ก๋๋ push O(1), pop O(1) ์ด๋ค.
ํ์ฉ ์์๋ ํ์ ํ๊ธฐ๋ฒ ์ฐ์ฐ, ๊ดํธ ์ ํจ์ฑ ๊ฒ์ฌ, ์น ๋ธ๋ผ์ฐ์ ๋ฐฉ๋ฌธ๊ธฐ๋ก(๋ค๋ก ๊ฐ๊ธฐ), ๊น์ด์ฐ์ ํ์(DFS) ๋ฑ์ด ์๋ค.
LIFO (Last In First Out)
stack์ ์๊ฐ ์์์ ๊ฐ์ฅ ์ต๊ทผ์ ์ถ๊ฐํ ๋ฐ์ดํฐ๊ฐ ๊ฐ์ฅ ๋จผ์ ๋์ค๋ ํ์ ์ ์ถ LIFO (Last In First Out) ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
push & pop
stack์์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ push๋ผ๊ณ ํ๊ณ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ๊ฒ์ pop์ด๋ผ๊ณ ํ๋ค.
push์ ๊ฒฝ์ฐ stack์ ๋งจ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ฉด ์๋ฃ๋๊ธฐ ๋๋ฌธ์ ์๊ฐ๋ณต์ก๋๋ O(1)์ด๋ค.
์ด์ ๋์ผํ๊ฒ pop์ ๊ฒฝ์ฐ๋ ๋งจ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๋ฉด ์๋ฃ๋๊ธฐ ๋๋ฌธ์ O(1)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ๋๋ค.
push์ pop์ ๋ชจ๋ stack์ top์ ์์๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ญ์ ํ๋ ํ์์ผ๋ก ํ์ฑ๋๋ค.
Stack ๋ ๊ฐ๋ฅผ ์ด์ฉํ์ฌ Queue ๊ตฌํ
queue์ enqueue()๋ฅผ ๊ตฌํํ ๋ ์ฒซ ๋ฒ์งธ stack์ ์ฌ์ฉํ๊ณ ,
dequeue()๋ฅผ ๊ตฌํํ ๋ ๋ ๋ฒ์งธ stack์ ์ฌ์ฉํ๋ฉด queue๋ฅผ ๊ตฌํํ ์ ์๋ค.
ํธ์์ enqueue()์ ์ฌ์ฉํ stack์ instack์ด๋ผ๊ณ ๋ถ๋ฅด๊ณ dequeue()์ ์ฌ์ฉํ stack์ outstack์ด๋ผ๊ณ ์นญํ๊ฒ ๋ค.
๋ ๊ฐ์ stack์ผ๋ก queue๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
- enqueue() :: instack์ push()๋ฅผ ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ค.
- dequeue() ::
- ๋ง์ฝ outstack์ด ๋น์ด ์๋ค๋ฉด instack.pop() ์ ํ๊ณ outstack.push()๋ฅผํ์ฌ instack์์ outstack์ผ๋ก ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ฎ๊ฒจ ๋ฃ๋๋ค. ์ด ๊ฒฐ๊ณผ๋ก ๊ฐ์ฅ ๋จผ์ ์๋ ๋ฐ์ดํฐ๋ outstack์ top์ ์์นํ๊ฒ ๋๋ค.
- outstack.pop()์ ํ๋ฉด ๊ฐ์ฅ ๋จผ์ ์๋ ๋ฐ์ดํฐ๊ฐ ๊ฐ์ฅ ๋จผ์ ์ถ์ถ๋๋ค.(FIFO)
class Queue(object):
def __init__(self):
self.instack=[]
self.outstack=[]
def enqueue(self,element):
self.instack.append(element)
def dequeue(self):
if not self.outstack:
while self.instack:
self.outstack.append(self.instack.pop())
return self.outstack.pop()
Queue ๋ ๊ฐ๋ฅผ ์ด์ฉํ์ฌ Stack ๊ตฌํ
queue ๋ ๊ฐ๋ฅผ ์ฌ์ฉํ์ฌ stack์ push์ pop์ ๊ตฌํํ๋ ๊ฒ์ ์ด์ ์ ๋ง์ถฐ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ฉด ๋๋ค.
ํธ์์ push()์ ์ฌ์ฉํ queue๋ q1์ด๋ผ๊ณ ๋ถ๋ฅด๊ณ pop()์ ์ฌ์ฉํ queue๋ฅผ q2๋ผ๊ณ ์นญํ๊ฒ ๋ค.
๋ ๊ฐ์ queue๋ก stack์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
- push() :: q1์ผ๋ก enqueue()๋ฅผ ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ค.
- pop() ::
- q1์ ์ ์ฅ๋ ๋ฐ์ดํฐ์ ๊ฐ์๊ฐ 1 ์ดํ๋ก ๋จ์ ๋๊น์ง dequeue()๋ฅผ ํ ํ, ์ถ์ถ๋ ๋ฐ์ดํฐ๋ฅผ q2์ enqueue() ํ๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๊ฐ์ฅ ์ต๊ทผ์ ๋ค์ด์จ ๋ฐ์ดํฐ๋ฅผ ์ ์ธํ ๋ชจ๋ ๋ฐ์ดํฐ๋ q2๋ก ์ฎ๊ฒจ์ง๋ค.
- q1์ ๋จ์ ์๋ ํ๋์ ๋ฐ์ดํฐ๋ฅผ dequeue()ํด์ ๊ฐ์ฅ ์ต๊ทผ์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ๋ค(LIFO)
- ๋ค์์ ์งํ๋ pop()์ ์์ ๊ฐ์ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ์งํํ๊ธฐ ์ํด q1๊ณผ q2์ ์ด๋ฆ์ swap ํ๋ค.
import queue
class Stack(object):
def __init__(self):
self.q1 = queue.Queue()
self.q2 = queue.Queue()
def push(self, element):
self.q1.put(element)
def pop(self):
while self.q1.qsize() > 1:
self.q2.put(self.q1.get())
temp = self.q1
self.q1 = self.q2
self.q2 = temp
return self.q2.get()
์๊ฐ๋ณต์ก๋
push() | q1.enqueue()๋ฅผ ํ๋ฒ๋ง ํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ O(1)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ๋๋ค. |
pop() | q1์ ์ ์ฅ๋์ด ์๋ n๊ฐ์ ์์ ์ค์ n-1๊ฐ๋ฅผ q2๋ก ์ฎ๊ฒจ์ผํ๋ฏ๋ก O(n)์ด ๋๋ค. |
Queue์ priority queue ๋น๊ต ์ค๋ช
Queue ์๋ฃ๊ตฌ์กฐ๋ ์๊ฐ ์์์ ๋จผ์ ์ง์ด ๋ฃ์ ๋ฐ์ดํฐ๊ฐ ๋จผ์ ๋์ค๋ ์ ์ ์ ์ถ FIFO(First In First Out) ๊ตฌ์กฐ๋ก ์ ์ฅํ๋ ํ์์ด๋ค. ์ด์ ๋ค๋ฅด๊ฒ ์ฐ์ ์์ ํ(priority queue)๋ ๋ค์ด๊ฐ ์์์ ์๊ด์์ด ์ฐ์ ์์๊ฐ ๋์ ๋ฐ์ดํฐ๊ฐ ๋จผ์ ๋์จ๋ค.
Queue์ operation ์๊ฐ๋ณต์ก๋๋ enqueue O(1), dequeue O(1)์ด๊ณ ,
Priority queue๋ push O(logn), pop(logn)์ด๋ค.
์ฐ์ ์์ ํ๋ ๊ตฌํ ๋ฐฉ๋ฒ๊ณผ operation์ ์๊ฐ๋ณต์ก๋๋ฅผ ์ดํดํ๋ ๊ฒ์ด ์ค์ํ๋ค.
์ฐ์ ์์ ํ๋ฅผ ๊ตฌํํ๋ผ๋ ๊ฒ์ Heap์ ๊ตฌํํ๋ฉด ๋๋ค.
Heap ์๋ฃ๊ตฌ์กฐ๋ ์ด์ง์์ ํธ๋ฆฌ๋ฅผ ํ์ฉํ๋ ๊ฒ์ด๊ณ , ๋ํ์ ์ธ operation์ ์๊ฐ๋ณต์ก๋๋ push O(logn), pop O(logn)์ด๋ค.
์ด ๋๊ฐ์ง ํน์ง์ ์ค์ฌ์ผ๋ก ๊ณต๋ถํ๋ฉด ๋๋ค. ๋ํ tree๊ฐ ๊ทธ๋ ค์ ธ ์๋ ์ํ์์ ์ต๋ํ, ์ต์ํ์ ์ฝ์ ๊ณผ ์ญ์ ์์ ์ด๋ป๊ฒ node๊ฐ ์ญ์ ๋๊ณ ์ฐ๊ฒฐ์ด ๋ณ๊ฒฝ๋๋์ง์ ๊ณผ์ ์ ๊ทธ๋ ค์ ์ค๋ช ํ ์ ์๋ค๋ฉด ๋ ์ข๋ค.
Heap
Heap์ ๊ทธ ์์ฒด๋ก ์ฐ์ ์์ํ (priority queue)์ ๊ตฌํ๊ณผ ์ผ์นํ๋ค.
Heap์ ์์ ์ด์งํธ๋ฆฌ ๊ตฌ์กฐ์ด๋ค. Heap์ด ๋๊ธฐ ์ํ ์กฐ๊ฑด์ ๋ค์๊ณผ ๊ฐ๋ค.
- ๊ฐ node์ ์ ์ฅ๋ ๊ฐ์ child node๋ค์ ์ ์ฅ๋ ๊ฐ๋ณด๋ค ์๊ฑฐ๋ ๊ฐ๋ค.(min heap)
root node์ ์ ์ฅ๋ ๊ฐ์ด ๊ฐ์ฅ ์์ ๊ฐ์ด ๋๋ค.
Heap ๊ตฌํ
ํธ๋ฆฌ๋ ๋ณดํต Linked list๋ก ๊ตฌํํ๋ค. ํ์ง๋ง Heap์ tree์์๋ ๋ถ๊ตฌํ๊ณ array๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํํด์ผ ํ๋ค.
๊ทธ ์ด์ ๋ ์๋ก์ด node๋ฅผ ํ์ '๋ง์ง๋ง ์์น'์ ์ถ๊ฐํด์ผ ํ๋๋ฐ, ์ด ๋ array๊ธฐ๋ฐ์ผ๋ก ๊ตฌํํด์ผ ์ด ๊ณผ์ ์ด ์์ํด์ง๊ธฐ ๋๋ฌธ์ด๋ค.
- ๊ตฌํ์ ํธ์๋ฅผ ์ํด array์ 0๋ฒ ์งธ index๋ ์ฌ์ฉํ์ง ์๋๋ค.
- ์์ ์ด์งํธ๋ฆฌ์ ํน์ฑ์ ํ์ฉํ์ฌ array์ index๋ง์ผ๋ก ๋ถ๋ชจ ์์๊ฐ์ ๊ด๊ณ๋ฅผ ์ ์ํ๋ค.
- n๋ฒ ์งธ node์ left child node = 2n
- n๋ฒ ์งธ node์ right child node = 2n + 1
- n๋ฒ ์งธ node์ parent node = n/2
Heap push - O(logn)
heap tree์ ๋์ด๋ logN์ด๋ค.
push()๋ฅผ ํ์ ๋, swapํ๋ ๊ณผ์ ์ด ์ต๋ logN๋ฒ ๋ฐ๋ณต๋๊ธฐ ๋๋ฌธ์ ์๊ฐ๋ณต์ก๋๋ O(logn)์ด๋ค.
์๋ ๊ทธ๋ฆผ์ 2๊ฐ push() ๋๊ณ min heap ์กฐ๊ฑด์ ๋ง์ถฐ ์ฌ๊ตฌ์ฑ๋๋ ๊ณผ์ ์ด๋ค.
Heap pop - O(logn)
pop()์ ํ์ ๋, swapํ๋ ๊ณผ์ ์ด ์ต๋ logN๋ฒ ๋ฐ๋ณต๋๊ธฐ ๋๋ฌธ์ ์๊ฐ๋ณต์ก๋๋ O(logn)์ด๋ค
- ๊ฐ node์ ์ ์ฅ๋ ๊ฐ์ child node๋ค์ ์ ์ฅ๋ ๊ฐ๋ณด๋ค ์๊ฑฐ๋ ๊ฐ๋ค.(mix heap)
root node์ ์ ์ฅ๋ ๊ฐ์ด ๊ฐ์ฅ ํฐ ๊ฐ์ด ๋๋ค.
์๋ ๊ทธ๋ฆผ์ 2๊ฐ pop()๋๊ณ ๋ง์ง๋ง ๋ ธ๋๊ฐ root node์ ์ฌ๋ผ์ค๊ณ Min heap ์กฐ๊ฑด์ ๋ง๊ฒ ์ฌ๊ตฌ์ฑํ๋ค.
์ฐธ๊ณ
https://lamarr.dev/images/algorithm/queue.jpg
https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS3EliS7H7AdMinqJ17goQtOBS7C27nRjK9cA&usqp=CAU
https://i.stack.imgur.com/LQJBQ.png
https://leetcode.com/media/original_images/225_stack_using_queues_pushB.png
https://i.imgur.com/1mghTRv.png
https://www.techiedelight.com/wp-content/uploads/2016/11/Pop-min-heap.png
'๐ป Computer Science > ์๋ฃ๊ตฌ์กฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ธ์(Argument)์ ํ๋ผ๋ฏธํฐ(Parameter) ์ฐจ์ด (0) | 2024.02.16 |
---|---|
Hash table & BST(Binary Search Tree) ๋? (0) | 2023.05.25 |
Array & Dynamic Array & Linked List ๋? ์ฐจ์ด์ (0) | 2023.05.22 |