[ Java ] Stack(스택) & Queue(큐) 개념 정리

chorok ☘️·2025년 6월 17일
0

Java 개념

목록 보기
3/7
post-thumbnail

STACK

  • LIFO(Last In, First Out) 구조 ⇒ “나중에 들어온 게 먼저 나간다!”
  • 쉽게 말해서 티슈 구조. 티슈를 만들 때는 먼저 넣은 티슈가 가장 아래, 사용할 때는 맨 위에 있는 티슈부터 사용하잖아!
  • FILO(Fast In, Last Out), 선입후출
  • ex.
    • 웹 브라우저의 뒤로 가기 (뒤로 가기 할 때 마지막 방문한 페이지부터 나감)
    • 함수 호출(재귀 함수 호출 시 가장 마지막 호출된 함수가 먼저 종료됨)
    • 괄호 검사(올바른 괄호 문자열 판별할 때 사용)

📌 기본 용어 / method

스택에서 삽입하는 연산을 푸시, 꺼내는 연산을

push(값) → 값을 스택에 넣기 —왼쪽부터 넣기
pop() → 스택에서 값을 꺼내기 —오른쪽부터 꺼내기
peek() → 스택의 맨 위 값을 확인 (꺼내진 않음) —오른쪽 값
isEmpty() → 스택이 비어있는지 확인

import java.util.Stack;

public class StackExample {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();

        // push(): 값 추가
        stack.push(10);
        stack.push(20);
        stack.push(30);

        System.out.println(stack);  // [10, 20, 30]
        System.out.println(stack.size());  // 3

        // pop(): 값 꺼내기 (맨 위 값)
        System.out.println(stack.pop());  // 30
        System.out.println(stack);  // [10, 20]

        // peek(): 맨 위 값 확인
        System.out.println(stack.peek());  // 20 -- 꺼내진 않음 ! 
        System.out.println(stack);  // [10, 20]

        // isEmpty(): 비어있는지 확인
        System.out.println(stack.isEmpty());  // false

        // 모든 값 꺼내기
        stack.pop();
        stack.pop();
        System.out.println(stack.isEmpty());  // true
    }
}
  • 언제 사용?
    데이터를 단순히 저장하고 순서와 상관없이 임의 접근하기만 해도 되면 배열을 사용하지만
    최근에 삽입한 데이터를 대상으로 뭔가 연산을 해야한다면 스택을 떠올려라!

QUEUE

  • FIFO(First In, First Out) 구조 ⇒ “먼저 들어온 게 먼저 나간다!”
  • 쉽게 말해서 줄 서기 구조. 버스 줄 서면, 가장 먼저 선 사람이 먼저 탑승하잖아!
  • ex.
    • 프린터 작업(먼저 요청한 인쇄 작업이 먼저 실행됨)
    • 프로세스 스케줄링(운영체제에서 먼저 실행 요청한 프로세스를 먼저 실행)
    • BFS(너비 우선 탐색) 알고리즘

📌 기본 용어

큐에서 삽입하는 연산을 enqueue(add), 꺼내는 연산을 dequeue(poll)

add(값) → 값을 큐에 넣기 —왼쪽부터 넣기 offer(값)으로도 가능하나 근소한 차이로 add가 빠름.
poll() → 큐에서 값을 꺼내기 —왼쪽부터 꺼냄
peek() → 큐의 맨 앞 값 확인 —왼쪽 값
isEmpty() → 큐가 비어있는지 확인

import java.util.LinkedList;
import java.util.Queue;

public class QueueExample {
    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();

        // offer(): 값 추가
        queue.offer(10);
        queue.offer(20);
        queue.offer(30);

        System.out.println(queue);  // 출력: [10, 20, 30]

        // poll(): 값 꺼내기 (맨 앞 값)
        System.out.println(queue.poll());  // 출력: 10
        System.out.println(queue);  // 출력: [20, 30]

        // peek(): 맨 앞 값 확인
        System.out.println(queue.peek());  // 출력: 20
        System.out.println(queue);  // 출력: [20, 30]

        // isEmpty(): 비어있는지 확인
        System.out.println(queue.isEmpty());  // 출력: false

        // 모든 값 꺼내기
        queue.poll();
        queue.poll();
        System.out.println(queue.isEmpty());  // 출력: true
    }
}

덱: Double Ended Queue를 줄인 말.

양 끝에서 삽입이나 삭제할 수 있는 큐이다.

ArrayDeque<Integer> queue = new ArrayDeque<>();

//큐에 데이터 추가
queue.addLast(1);
queue.addLast(2);
queue.addLast(3);

//큐의 맨 앞 데이터를 제거하면서 반환 
int first = queue.pollFirst();
System.out.println(first);  // 1

//큐에 데이터 추가
queue.addLast(4);
queue.addLast(5);

//큐의 맨 앞 데이터를 제거하면서 반환 
first = queue.pollFirst();
System.out.println(first);  // 2

addFirst()로만 넣고, pollFirst()로만 꺼내면 동작은 스택의 push, pop과 동일하므로 ArrayDeque 하나면 큐, 스택 그리고 덱을 전부 구현할 수 있다.


PriorityQueue

들어가는 순서와는 상관없이 우선순위가 높은 데이터가 먼저 나가는 자료구조
즉, 내부적으로는 정렬된 구조를 유지하면서, poll 연산 시 가장 높은(또는 낮은) 우선순위가 빠져나온다.

// 기본형: 우선순위가 낮은 숫자가 먼저 나옴 (작은 숫자)
PriorityQueue<Integer> pQ = new PriorityQueue<>();
 
// 우선순위가 높은 숫자가 먼저 나옴 (큰 숫자)
PriorityQueue<Integer> pQ = new PriorityQueue<>(Collections.reverseOrder());
  • Heap(힙) 같은 자료구조로 구현한다.

❓ 왜 "우선순위 큐"일까?

핵심은 “꺼낼 때” 기준!!

큐라는 개념은 "데이터를 넣고 → 빼는 과정에서 어떤 규칙으로 나오느냐"를 설명하는데, 우선순위 큐는 "들어간 순서" 대신 "우선순위 규칙"으로 나오는 큐이다.

반대로 스택은 “최근 것부터 빼내는 것(LIFO)”라는 규칙이 이미 정해져 있다.
→ 우선순위를 넣으면 스택(LIFO)의 정의와 충돌
(예: 스택은 무조건 맨 위(top) 원소를 꺼내야 하는데, 우선순위에 따라 중간 원소를 빼야 할 수도 있잖아?)



참고 자료: 코딩테스트 합격자 되기 : 자바편
profile
백엔드 개발자 chorok's velog

0개의 댓글