스택 (Stack)

스택은 데이터를 LIFO(Last In First Out) 방식으로 관리하는 선형 자료구조입니다. 즉, 마지막에 추가된 데이터가 가장 먼저 제거됩니다. 접시 쌓기와 같은 일상적인 상황과 유사합니다.

스택의 주요 특징

  1. LIFO(Last In First Out):
    • 나중에 삽입된 데이터가 먼저 제거됩니다.
    • Top: 스택의 가장 위쪽(마지막 데이터).
    • Bottom: 스택의 가장 아래쪽(첫 번째 데이터).
  2. 기본 연산:
    • Push: 데이터를 스택의 Top에 추가.
    • Pop: 데이터를 스택의 Top에서 제거.
    • Peek: Top에 있는 데이터를 확인(제거하지 않음).
    • isEmpty: 스택이 비었는지 확인.
  3. 추상 자료형(ADT):
    • 스택은 배열이나 연결 리스트로 구현 가능합니다.
public class ArrayStack {
    private int[] stack;  // 스택을 저장할 배열
    private int top;      // 스택의 Top을 가리키는 인덱스

    // 스택 생성자
    public ArrayStack(int capacity) {
        stack = new int[capacity];  // 고정 크기 배열
        top = -1;  // 스택이 비어 있음을 나타냄
    }

    // Push: 데이터 추가
    public void push(int data) {
        if (top == stack.length - 1) {
            throw new IllegalStateException("Stack is full!");  // 스택 오버플로우
        }
        stack[++top] = data;  // Top을 증가시키고 데이터 저장
    }

    // Pop: 데이터 제거 및 반환
    public int pop() {
        if (isEmpty()) {
            throw new IllegalStateException("Stack is empty!");  // 스택 언더플로우
        }
        return stack[top--];  // 데이터를 반환한 후 Top 감소
    }

    // Peek: Top 데이터 확인
    public int peek() {
        if (isEmpty()) {
            throw new IllegalStateException("Stack is empty!");
        }
        return stack[top];
    }

    // 스택이 비었는지 확인
    public boolean isEmpty() {
        return top == -1;
    }

    // 스택의 현재 크기 반환
    public int size() {
        return top + 1;
    }

    // 스택의 데이터 출력 (디버깅용)
    public void printStack() {
        System.out.print("Stack: ");
        for (int i = 0; i <= top; i++) {
            System.out.print(stack[i] + " ");
        }
        System.out.println();
    }

    // 테스트
    public static void main(String[] args) {
        ArrayStack stack = new ArrayStack(5); // 크기 5인 스택 생성

        stack.push(10);
        stack.push(20);
        stack.push(30);
        stack.printStack();  // 출력: Stack: 10 20 30

        System.out.println("Peek: " + stack.peek());  // 출력: Peek: 30
        System.out.println("Popped: " + stack.pop()); // 출력: Popped: 30
        stack.printStack();  // 출력: Stack: 10 20

        stack.push(40);
        stack.push(50);
        stack.push(60);
        stack.printStack();  // 출력: Stack: 10 20 40 50 60

        // Uncomment the following line to test stack overflow
        // stack.push(70); // 예외 발생: Stack is full!
    }
}