swift 자료구조 queue 코드로 정리2 - stack을 이용해서 구현
지난 포스팅(swift 자료구조 queue 코드로 정리 - 큐 일상생활 예제)에서 큐의 기본 정의와 array로 큐를 구현해 보았습니다.
지난 포스팅에 이어서 이번 포스팅에는 두개의 스택을 이용해서 큐를 구현해 보고자 합니다.
두개의 스택 leftStack과 rightStack 변수를 생성합니다. 이 두 변수의 타입은 배열 입니다.
왼쪽 스택과 오른쪽 스택 모두 합쳐서 하나의 스택이 되는 구조입니다.
그럼 왼쪽 스택과 오른쪽 스택은 각각 무슨 용도일까요?
먼저 오른쪽 스택은 큐에서 enqueue 에 사용됩니다.
즉, 자료구조 큐에 데이터를 삽입을 하면 오른쪽 스택(rightStack)에 삽입을 합니다.
왼쪽스택은 큐의 dequeue에 사용됩니다.
즉, 자료구조 큐에서 데이터를 꺼낼때 왼쪽 스택(leftStack)에서 꺼냅니다.
더블 스택 구현
먼저 아래와 같이 구조체로 더블스택을 만들어주고, 두개의 스택 변수를 작성해 줍니다.
// 더블 스택 구현
public struct QueueStack<T>:Queue{
public typealias Element = T
// 아래 array 두개 합해서 전체 stack 임.
// 디큐 담당 array
private var leftStack:[T] = []
// 인큐 담당 array
private var rightStack:[T] = []
public init() { }
}
// 출력용
extension QueueStack:CustomStringConvertible{
public var description: String{
let printLast = leftStack.reversed() + rightStack
return String(describing: printLast)
}
}
enqueue 함수
위에서 enqueue는 오른쪽 배열 제일 마지막에 값을 넣는다고 정의했습니다.
// enqueue는 우측 스택(array)에 넣는다.
public mutating func enqueue(_ element: T) -> Bool {
rightStack.append(element)
return true
}
isEmpty
또한 두 배열 모두 더해서 하나의 큐라고 정의했기 때문에 큐의 빈값을 체크할 때도 두 배열 모두 비었는지 체크 합니다.
// 왼쪽 스택과 오른쪽 스택이 모두 비어야 empty
public var isEmpty: Bool{
return leftStack.isEmpty && rightStack.isEmpty
}
dequeue
큐에서 값을 꺼낼 때는 왼쪽 배열에서 꺼낸다고 했습니다.
이때 주목해볼 부분이 왼쪽 배열에 값이 처음에는 없다는 것입니다.
위에서 큐에 데이터를 삽입 할 때는 오른쪽 배열에 넣어준다고 했는데, 당연히 왼쪽 배열에는 아무 값이 없습니다.
따라서 왼쪽 배열은 처음에는 비어있습니다.
그리고 오른쪽 배열을 거꾸로 뒤집에서 왼쪽 배열에다가 넣어주고 오른쪽 배열은 전부 비워줍니다.
그럼 왼쪽 배열에서 popLast 하면 배열의 제일 앞에 있던 요소가 reversed() 함수 호출로 제일 뒤로 이동 했기 때문에 큐의 형태와 동일하게 dequeue 처리가 됩니다.
public mutating func dequeue() -> T? {
//좌측 스택이 비어 있으면
//우측 배열 뒤집어서 좌측 스택에 할당해주고 좌측스택(array)의 마지막 요소를 삭제한다.
if leftStack.isEmpty{
leftStack = rightStack.reversed()
rightStack.removeAll()
}
return leftStack.popLast()
}
peek
큐의 제일 앞에 있는 요소를 리턴하는 함수 입니다.
왼쪽 배열이 안비었으면 왼쪽 배열의 마지막에서 요소를 꺼냅니다.
왜 왼쪽 배열은 마지막 요소를 꺼낼까요?
왜냐면 왼쪽 배열은 오른쪽 배열을 reversed() 거꾸로 뒤집었기 때문에 배열의 제일 앞에 있는 요소가 제일 뒤로가있기 때문입니다.
이어서 왼쪽 배열이 비었으면 우측 배열의 제일 첫번째 요소를 리턴해줍니다.
public var peek: T?{
return !leftStack.isEmpty ? leftStack.last : rightStack.first
}
QueueStack 테스트
아래와 같이 스택큐를 생성하고 강아지, 새, 토끼, 거북이를 순서대로 인큐 했습니다.
그리고 한번의 peek 와 한번의 dequeue, 그리고 공룡을 enqueue 했습니다.
var queueStack = QueueStack<String>()
queueStack.enqueue("강아지")
queueStack.enqueue("새")
queueStack.enqueue("토끼")
queueStack.enqueue("거북이")
print("\n")
print(queueStack)
print(queueStack.isEmpty)
print(queueStack.peek)
queueStack.dequeue()
print("\n")
print(queueStack)
queueStack.enqueue("공룡")
print("\n")
print(queueStack)
출력
["강아지", "새", "토끼", "거북이"]
false
Optional("강아지")
["새", "토끼", "거북이"]
["새", "토끼", "거북이", "공룡"]
성능
참고
코딩퀴즈 - ios
https://apps.apple.com/kr/app/%EC%BD%94%EB%94%A9%ED%80%B4%EC%A6%88/id1625309702
코딩퀴즈 - aos
https://play.google.com/store/apps/details?id=com.codingquiz.myapplication
https://www.raywenderlich.com/books/data-structures-algorithms-in-swift/
'자료구조&알고리즘 > 기본개념' 카테고리의 다른 글
swift 알고리즘 - 버블정렬 쉽게 이해하기 (0) | 2022.08.10 |
---|---|
swift 알고리즘 - 선택정렬 한방에 이해하기 (0) | 2022.08.09 |
swift 자료구조 queue 코드로 정리 - 큐 일상생활 예제 (0) | 2022.08.08 |
swift 자료구조 stack 코드로 정리 - 스택 일상생활 예제 (0) | 2022.08.08 |
swift 자료구조 - 연결리스트 코드로 정리 - 2 (0) | 2022.08.06 |