[Algorithm] Queue

BruniOS
4 min readMar 11, 2024

--

오늘은 Queue에 대해 알아보자

Queue

Queue는 FIFO(First In First Out)의 특성을 가지고 있다.

즉 먼저 들어간 순서대로나가는 것이다

구조

public struct Queue<T> {
private var data = [T]()
public init() {}

public mutating func enqueue(element: T) {
data.append(element)
}
public mutating func dequeue() -> T?{
return isEmpty ? nil : data.removeFirst()
}

public var size : Int {
return queue.count
}

public var isEmpty : Bool {
return queue.isEmpty
}
}

기본적인 함수

  • Enqueue : Queue의 맨 뒤에 원소를 추가한다.
  • Dequeue : Queue의 맨 앞에 원소를 삭제한다.
  • Peek : Queue의 맨앞 데이터를 읽는다.
  • Front : Queue의 맨 앞 index
  • Back : Queue의 맨 뒤 index

삽입 — Enqueue

public mutating func enqueue(element: T) {
data.append(element)
}

삭제 — Dequeue

public mutating func dequeue() -> T?{
return isEmpty ? nil : data.removeFirst()
}

비효율적인 removeFirst()

removeFirst()는 값을 삭제하고 이동시키므로, O(n)의 시간복잡도를 가진다.

따라서 좀더 효율성이 좋은 코드를 만들어봤다.

배열을 가리키는 변수를 두어서, 한 칸씩 이동하는 것이다.

2개의 Stack을 사용한 Queue

public struct Queue<T> {
private var leftStack = [T]() // dequeue stack 용
private var rightStack = [T]() // enqueue stack 용
public init() {}

public mutating func enqueue(element: T) {
rightStack.append(element)
}
public mutating func dequeue() -> T?{
if leftStack.isEmpty {
leftStack = rightStack.reversed()
rightStack.removeAll()
}
return leftStack.popLast()
}

public var size : Int {
return queue.count
}

public var isEmpty : Bool {
return leftStack.isEmpty && rightStack.isEmpty
}

public var peek : T? {
return leftStack.empty ? rightStack.first : leftStack.last
}
}

원리는 다음과 같다

i) enqueue, dequeue 할 Stack 2개를 만든다

ii) dequeue Stack이 비어있을 경우 enqueue Stack에 있는 값들을 dequeue Stack에 reverse 해서 넣는다.

iii) 이후 dequeue를 할 경우, 마지막값을 리턴한다.

이런식으로 하면 기존 dequeue가 O(n)인 것이 O(1)이 된다.

--

--

BruniOS
BruniOS

No responses yet