큐 (Queue)
이 정리는 위키백과를 참고하였습니다.
FIFO
: 선입선출(First In First Out), 제일 먼저 들어간 것이 제일 먼저 나간다는 뜻입니다.- 예시: 카페 주문, 선입선출 물건 판매 (유통기한)
- 큐는 양 쪽 끝에서 자료를 넣거나 뺄 수 있는 선형의 자료 구조입니다.
- 하지만 한 쪽(rear)에서는 삽입만, 반대쪽(front)에서는 삭제만 일어납니다.
- 맨 처음에 들어온 데이터의 위치를
front
(혹은first
)이라고 합니다. - 큐는 그래프 자료구조 탐색방법 중
BFS
(Breath First Search, 깊이우선 탐색)에 쓰입니다. - 그 외에 CPU 스케쥴링 등의 프로세스, 자원을 공유하는 대부분의 경우에 큐가 사용됩니다.
- 기본적으로 추상 자료형(Abstract Data Type,
ADT
)이지만 여기서는 자료 구조의 영역까지 다룰 것입니다. (구현까지)
구현 방법 - Stack과 동일
- 1차원 배열: 구현하기 쉽지만
input
의 개수를 알아야 합니다. - 연결 리스트: 구현이 배열보다 어렵고 메모리를 좀 더 사용하지만, 유동적으로
input
에 대처할 수 있습니다.
함수
가장 보편적으로 사용되는 함수를 골라보았습니다. 이외에
size()
등의 함수들도 사용자가 정의하여 쓸 수 있습니다.
Q.front()
: 큐의 가장 앞 데이터(front
)를 반환합니다.Q.deque()
:first
을 반환하고 스택에서 삭제합니다.Q.enque()
: 큐의 끝에(rear) 새로운 데이터를 삽입합니다.Q.isEmpty()
: 큐가 비었으면True
, 아니면False
을 반환합니다.
큐 구현 코드 (Python, C++)
Python
: 큐 라이브러리가 따로 존재하지만 list를 이용하여 구현해 보았습니다.- 파이썬에서는 리스트에서
remove
를 할 때마다 자동으로 인덱스가 조정되기 때문에 항상 0 위치의 원소를deque
하거나front
할 때 사용했습니다.
- 파이썬에서는 리스트에서
class queue:
def __init__(self):
self.items = []
def enque(self, item):
self.items.append(item)
def deque(self):
tmp = self.items[0] # 첫 번째 원소 tmp에 저장
self.items.remove(tmp) # item에서 삭제
return tmp # tmp 반환
def isEmpty(self):
return not self.items
def front(self):
return self.items[0] # 첫 번째 원소 반환
q = queue()
print(q.isEmpty()) # True 출력
q.enque(1)
q.enque(2)
print(q.deque()) # 1 출력
q.enque(3)
print(q.front()) # 2 출력
print(q.isEmpty()) # False 출력
C++
: 노드를 이용한 연결리스트로 스택을 구현해 보았습니다.
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
Node() {
next = NULL;
data = 0;
}
Node(int i, Node* ptr) {
data = i;
next = ptr->next;
ptr->next = this;
}
};
struct Queue {
Node* first;
Node* rear; // 큐에는 맨 뒤를 가리키는 포인터 필요
int count;
Queue() {
first = new Node();
rear = new Node(); // 둘 다 next값을 NULL로 초기화
count = 0;
}
int deque() {
if (count != 0) {
int res = first->data;
first = first->next;
count--;
return res;
}
}
int front() {
if (count != 0) {
return first->data;
}
}
bool isEmpty() {
if (count == 0) {
return true;
}
else return false;
}
void enque(int data) { // 스택과 다른 삽입과정
Node* node = new Node();
node->data = data;
node->next = NULL; // 삽입될 노드의 next값을 NULL로 설정
if (count == 0) { // 첫 숫자일 때 첫 번째 노드로 설정
first = node;
}
else { // 기존 rear의 next값을 현 node로 갱신
rear->next = node;
}
rear = node; // 맨 마지막을 node로 갱신(공통)
count++;
}
};
int main() {
Queue* q = new Queue();
cout << q->isEmpty() << '\n'; // 1 출력
q->enque(1);
q->enque(2);
cout << q->deque() << '\n'; // 1 출력
q->enque(3);
cout << q->front() << '\n'; // 2 출력
cout << q->isEmpty() << '\n'; // 0 출력
}
사담
오랜만에 자료구조를 보는데 C++로 노드랑 링크드 리스트 구현을 하는 게 너무 새롭네요..
그 때는 주먹구구 암기식으로 외웠던 것 같은데 포스팅의 장점은 정말 이해하려고 노력하게 만든다는 점 같아요🙌🙌
직접 구현해보는 게 중요하다는 말이 뭔지 이제야 알 것 같습니다!!
'자료구조' 카테고리의 다른 글
자료구조: 스택(Stack) (0) | 2020.07.26 |
---|---|
자료구조: 배열(Array)와 리스트(List) (0) | 2020.07.24 |