접시를 쌓듯이 자료를 차곡차곡 쌓아 올린 형태의 자료구조
파이썬에서 큐를 사용하는 가장 간단한 방법은 범용 자료 구조인 list
를 사용하는 것이다. list
객체의 pop(0)
함수를 호출하면 첫 번째 데이터를 제거할수 있다.
하지만 이 방법은 추천되지 않는다. 글을 그대로 옮겨쓰기보단, 설명을 옮겨서 적어두겠다.
- 하지만 이렇게 list
를 큐 자료 구조의 효과를 내기 위해서 사용하는 것은 성능 측면에서 추천되지 않습니다. 파이썬의 list
는 다른 언어의 배열처럼 무작위 접근(random access)에 최적화된 자료 구조이기 때문에 pop(0)
또는 insert(0, x)
는 성능적으로 매우 불리한 연산입니다.
이 두 연산은 시간 복잡도는 O(n)
이기 때문에 담고 있는 데이터의 개수가 많아질 수록 느려집니다. 왜냐하면 첫 번째 데이터를 제거한 후에는 그 뒤에 있는 모든 데이터를 앞으로 한 칸식 당겨줘야 하고, 맨 앞에서 데이터를 삽입하려면 그 전에 모든 데이터를 뒤로 한 칸씩 밀어줘야 하기 때문입니다.
이렇게 기존에 queue
가 담고 있던 모든 데이터를 앞/뒤로 쉬프트(shift)해주지 않으면 queue[i]
의 결과값이 정확하지 않을 것입니다.
collections
모듈의 deque
는 double-ended queue의 약자로 데이터를 양방향에서 추가하고 제거할 수 있는 자료 구조다. 이 deque를 활용해서 구현하는것이 파이썬 내의 큐 사용법 정석이다.
from collections import deque
deque 는 그림으로 이해하면 편한데, 나중에 한번에 그려서 추가하겠다. 쉽게 설명하자면, 양옆에서 넣고 빼는게 가능한 자료형이고, 활용하기 쉬운편이다.
스택과 마찬가지로, 개념을 이해하기 위해서는 백준 18258문제를 푸는게 좋다.
일단, 스택과 큐, 더 나아가서 힙은 무조건 알아둬야하는 자료형이다. 앞으로 학습하게 되는 dfs에는 스택, bfs, dp에는 큐를 활용하게 되는데, 정확하게 짚고 넘어가지 않으면 분명 브레이크가 걸릴것이다.
deque는 한번 더 정리하고 넘어가는게 좋을것 같다. deque는 양방향이기 때문에 append(), pop()과 더불어 appendleft(), popleft() 메소드가 있어 각각 맨 앞에 데이터를 삽입하거나 맨 앞에서 제거할 수 있다. appendleft(), popleft() 메소드는 각각 시간복잡도가 O(1)이기 때문에 리스트보다 더 효율적이다. 쉽게 말해서 큐를 풀이할때는 무조건 deque를 활용하는게 시간복잡도 면에서도, 풀이 면에서도 무조건 활용하는게 좋다.
공부 참고자료:
#https://www.acmicpc.net/problem/18258
#큐 2
#18258
import sys
from collections import deque
input = sys.stdin.readline
queue = deque()
n = int(input())
for _ in range(n):
a = input().split()
if a[0] == 'push':
queue.append(a[1])
elif a[0] == 'pop':
if queue:
print(queue.popleft())
else:
print(-1)
elif a[0] == 'size':
print(len(queue))
elif a[0] == 'empty':
if queue:
print(0)
else:
print(1)
elif a[0] == 'front':
if queue:
print(queue[0])
else:
print(-1)
elif a[0] == 'back':
if queue:
print(queue[-1])
else:
print(-1)