스위프트에서 큐를 구현해서 쓰려고 할 때, 기존에 편하게 쓰는 방법으로 removeFirst를 사용해서 pop을 구현해도 된다. 하지만 커서 큐나 더블 스택 큐를 구현해서 사용하면 훨씬 성능상의 이점을 가져올 수 있기 때문에 이를 이용하면 될 듯하다. 개인적으로는 더블 스택 큐가 구현이 어렵지 않으면서도 성능상으로 뛰어나다는 점, 그리고 콘셉트 자체가 마음에 들어서 선호하는 방법이다.
구글링을 하다보면 큐를 어떻게 구현하는지에 대해 써져 있는 다양한 글이 있는데 나 같은 바보에게 적합한 글이 없었다. 내가 헷갈리는 방향은 실제로 class와 제네릭을 이용하여 구현하는 것은 좋은데 구체적으로 그걸 어떻게 쓸지에 대해 안 써져 있는 것이었다.
거두절미하고 큐를 사용하고자 한다면 다음과 같은 방법을 생각할 수 있다.
1. 그때마다 Queue의 구현법을 생각하여 즉석으로 사용하기
2. 미리 만들어 놓고 push, pop등으로 짧은 코드로 사용하기
둘 다 나름의 장점이 있는 방법인듯하다. 내 경우 머릿속으로 정리가 안 되어 있다면 2번 방법을 선택하고 간단하면
func을 구현하여 사용하는 방법이 있고 그냥 안에 있는 함수를 이용하는 방법이 있다. 굳이 class로 구현하여하고 싶다면 혹은 구현되어 있는 걸 이용하고 아래와 같이 이용하면 된다.
class Queue<T> {
var enQueue: [T] = []
var deQueue: [T] = []
var count: Int {
return enQueue.count + deQueue.count
}
var isEmpty: Bool {
return enQueue.isEmpty && deQueue.isEmpty
}
init() { }
func push(_ element: T) {
enQueue.append(element)
}
func pop() -> T {
if deQueue.isEmpty {
deQueue = enQueue.reversed()
enQueue.removeAll()
}
return deQueue.popLast()!
}
}
-- 사용법 --
let q = Queue<Int>() // Int인 경우
혹은
let q = Queue<String>() // String인 경우
// 이제 메인 함수 내부에서 큐에 요소를 넣고 싶을때
q.enQueue.append(i)
혹은
q.push(i)
// 빼고 싶을때
if deQueue.isEmpty {
deQueue = enQueue.reversed()
enQueue.removeAll()
}
return deQueue.popLast()!
혹은
q.pop(i)
// 큐 안의 갯수가 필요할 때
q.count
// 큐가 비었는지 확인하고 싶을 때
q.isEmpty