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๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค (ํ‰๋‚ด๋‚ธ๋‹ค)