본문 바로가기
🖥️ Computer Science/Data Structure

[Swift] 스택(Stack) 구현하기

by hyebin (Helia) 2024. 9. 27.

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의 기본 동작을 구현했습니다.

 

  1. push(_:): 스택에 요소를 추가합니다.
  2. pop(): 스택의 맨 위 요소를 제거하고 반환합니다.
  3. isEmpty: 스택이 비어있는지 확인합니다.
  4. count: 스택의 요소 개수를 반환합니다.
  5. 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 구조체를 구현하는 것이 더 유리할 수 있습니다.

반응형

댓글