큐 개요
- 선입선출(FIFO) 구조를 가지고 있는 자료구조입니다.
- 먼저 집어넣은 데이터가 가장 먼저 나오는 자료구조입니다.
- 데이터를 임시로 저장했다가 나중에 꺼내서 사용할 때 유용합니다.
큐의 FIFO 원리
- 줄을 첫 번째 선 사람이 가장 먼저 서비스를 받습니다.
- 큐에서 제거될 첫 번째 항목은 앞쪽이기 때문에 head라고 합니다. 가장 최근에 추가된 위치는 가장 뒤쪽이기 때문에 rear라고 합니다.
큐 동작 원리
- enqueue(el) : 데이터를 큐의 뒤쪽에 추가합니다.
- dequeue() : 큐의 앞쪽에서 데이터를 제거 후 반환합니다.
- front() : 큐의 앞쪽에서 데이터를 제거하지 않고 반환합니다.
- isEmpty() : 큐가 비어있는지 확인합니다.
- size() : 큐의 크기를 반환합니다.
큐 배열 코드 예시
class Queue {
constructor() {
this.items = []
}
size() {
return this.items.length
}
isEmpty() {
return this.size() === 0
}
enqueue(el) {
this.items.push(el)
}
dequeue() {
if(this.isEmpty()) throw new Error('empty queue')
return this.items.shift()
}
front() {
if(this.isEmpty()) throw new Error('empty queue')
return this.items[0]
}
}
큐 링크드 리스트 코드 예시
class Node {
constructor(el) {
this.item = el
this.next = null
}
}
class Queue {
constructor() {
this.queue = null
this.length = 0
}
size() {
return this.length
}
isEmpty() {
return this.size() === 0
}
enqueue(el) {
const node = new Node(el)
if(this.isEmpty()) this.queue = node
else {
let current = this.queue
while(current.next) {
current = current.next
}
current.next = node
}
length++
}
front() {
if(this.isEmpty()) throw new Error('empty queue')
return this.queue.item
}
dequeue() {
const item = this.front()
this.queue = this.queue.next
length--
return item
}
}
하나의 구조에서만 하니 enqueue일때 while을 돌게됩니다.
그래서 2개의 구조를 만들어서 front와 rear로 구성하겠습니다.
class Node {
constructor(el) {
this.item = el
this.next = null
}
}
class Queue {
constructor() {
this.front = null
this.rear = null
this.length = 0
}
size() {
return this.length
}
isEmpty() {
return this.size() === 0
}
enqueue(el) {
const node = new Node(el)
if(this.isEmpty()) this.front = this.rear = node
else {
this.rear.next = node
this.rear = node
}
length++
}
peek() {
if(this.isEmpty()) throw new Error('empty queue')
return this.front.item
}
dequeue() {
const item = this.peek()
this.front = this.front.next
length--
return item
}
}
front 와 rear를 둬서 rear에 insert되는 node를 계속 둬서 같은 node를 바라보는 front next에도 영향이 가게끔 했습니다.
선형 큐 개요
- 고정된 크기를 가지는 자료구조로 최대 크기를 초과하면 더이상 데이터를 삽입할 수 없습니다.
선형 큐 작동원리
- enqueue(el) : rear 포인트를 증가 시킨 후 데이터를 추가합니다.
- dequeue() : front 포인트를 증가 시킨 후 데이터를 제거 후 반환합니다.
- peek() : 첫번째 데이터를 제거하지 않고 반환합니다.
- isEmpty() : front와 rear이 같으면 비어있습니다.
- isfull() : rear이 size - 1와 같으면 가득차있습니다.
- getSize() : 현재 큐가 생성된 사이즈를 반환합니다.
- getCount() : 현재 큐에 저장된 데이터 숫자를 반환합니다.
선형 큐 코드 예시
class Queue {
constructor(size) {
this.queue = new Array(size)
this.front = -1
this.rear = -1
this.count = 0
}
getSize() {
return this.queue.length
}
getCount() {
return this.count
}
isFull() {
return this.rear === (this.getSize() - 1)
}
isEmpty() {
return this.rear === this.front
}
enqueue(el) {
if(this.isFull()) throw new Error('full queue')
this.queue[++this.rear] = el
this.count++
}
peek() {
if(this.isEmpty()) throw new Error('empty queue')
return this.queue[this.front + 1]
}
dequeue() {
const item = this.peek()
this.front++
this.count--
return item
}
}
원형 큐 개요
- 고정된 크기를 가졌지만 큐의 앞과 뒤가 연결되어 있는 원형 구조를 가집니다.
- 큐가 가득 찬 상태에서 요소를 추가할 때, 새로운 요소를 큐의 첫 번째 위치로 이동시켜 공간을 확보할 수 있습니다.
- 나머지를 이용하여 위치를 이동시켜줍니다.
원형 큐 코드 예시
class Queue {
constructor(size) {
this.queue = new Array(size)
this.front = -1
this.rear = -1
this.count = 0
}
getSize() {
return this.queue.length
}
getCount() {
return this.count
}
isFull() {
return this.getCount() === this.getSize()
}
isEmpty() {
return this.getCount() === 0
}
#getIndex(n) {
return (n + 1) % this.getSize()
}
enqueue(el) {
if(this.isFull()) throw new Error('full queue')
this.rear = this.#getIndex(this.rear)
this.queue[this.rear] = el
this.count++
}
peek() {
if(this.isEmpty()) throw new Error('empty queue')
return this.queue[this.#getIndex(this.front)]
}
dequeue() {
const item = this.peek()
this.front = this.#getIndex(this.front)
this.count--
return item
}
}
큐 시간 복잡도
- 데이터 삽입, 삭제 O(1)를 가집니다.
큐 장점
- 데이터 접근, 삽입, 삭제가 빠릅니다.
큐 단점
- 중간에 있는 데이터를 가져오기가 어렵습니다.
큐 활용
- 작업 스케줄링
- 버퍼 구현
- 너비 우선 탐색
'알고리즘 > 자료구조' 카테고리의 다른 글
배열 요소에 접근하는데 O(1)의 시간이 걸리는 이유 (0) | 2024.04.04 |
---|---|
행렬인가 무엇인가? (0) | 2024.04.04 |
배열이란 무엇인가? (0) | 2024.04.04 |
자료 알고리즘 - 덱(Deque) 이해와 효율적인 구현 방법 (0) | 2024.03.21 |
자료구조 알고리즘 - 스택 이해와 효율적인 구현 방법 (0) | 2024.03.20 |