Stack을 구조체와 배열로 구현할 수 있습니다.
먼저 제네릭을 이용해 Stack 구조체를 정의하고, 주요 기능을 구현해보겠습니다.
struct Stack<T> {
private var stack: [T] = []
var isEmpty: Bool {
return stack.isEmpty
}
var count: Int {
return stack.count
}
var peek: T? {
return stack.last
}
mutating func push(_ element: T) {
stack.append(element)
}
mutating func pop() -> T? {
return stack.popLast()
}
}
위 코드에서는 Stack의 기본 동작을 구현했습니다.
- push(_:): 스택에 요소를 추가합니다.
- pop(): 스택의 맨 위 요소를 제거하고 반환합니다.
- isEmpty: 스택이 비어있는지 확인합니다.
- count: 스택의 요소 개수를 반환합니다.
- peek: 스택의 맨 위 요소를 반환하지만 제거하지는 않습니다.
이 Stack 구조체는 다음과 같이 사용할 수 있습니다
var intStack = Stack<Int>()
intStack.push(1)
intStack.push(2)
intStack.push(3)
print(intStack.pop()) // 출력: Optional(3)
print(intStack.peek) // 출력: Optional(2)
print(intStack.count) // 출력: 2
print(intStack.isEmpty) // 출력: false
또한, Stack을 별도의 구조체로 구현하지 않고도 Array를 사용해 비슷한 방식으로 Stack처럼 동작하도록 할 수 있습니다.
var arrayStack = [Int]()
arrayStack.append(1) // push
arrayStack.append(2)
print(arrayStack.popLast() ?? 0) // pop
print(arrayStack.last ?? 0) // peek
Array를 사용하는 경우 코드가 간단하고 직관적이지만, 몇 가지 단점이 있을 수 있습니다.
- 매번 스택 연산(push, pop 등)을 명시적으로 작성해야 합니다.
- 이 배열이 스택으로 사용된다는 의도가 명확하지 않아 다른 개발자가 코드를 이해하는 데 어려움을 겪을 수 있습니다
Stack 구현할 경우 다음과 같은 장점이 있습니다.
- 인터페이스 제한: 스택의 무결성을 유지하며, 불필요한 연산을 방지할 수 있습니다.
- 추상화: 내부 구현을 숨기고, 스택의 의도된 사용만 허용합니다.
- 타입 안정성: 제네릭을 사용해 다양한 타입에 대한 안전한 스택을 만들 수 있습니다.
시간 복잡도는 Array와 거의 동일하지만, 코드의 가독성, 안정성, 유지보수성 측면에서 팀 프로젝트에서는 Stack 구조체를 구현하는 것이 더 유리할 수 있습니다.
반응형
'🖥️ Computer Science > Data Structure' 카테고리의 다른 글
[Swift] Dequeue 구현하기 (0) | 2024.09.27 |
---|---|
[Swfit] 큐(Queue) 구현하기 (1) | 2024.09.27 |
[자료구조] 해시 테이블(Hash Table) (0) | 2023.03.15 |
[자료구조] 우선순위 큐(Priority Queue) (0) | 2023.03.13 |
[자료구조] 힙(Heap) (0) | 2023.03.13 |
댓글