
지난 포스팅에서 자주 사용되는 Array, ArrayList, LinkedList에 대해 알아봤다. 선형 자료구조에서 규칙을 정한게 스택과 큐다.
O(n) 삽입,삭제: O(1)
후입선출(LIFO) 성질을 가진 자료구조Array로 구현 (LinkedList도 가능)O(n)O(1) class Stack {
private int[] arr;
private int top;
private int capacity; // 스택의 최대 크기
public Stack(int size) {
arr = new int[size];
capacity = size;
top = -1; // 초기 top은 -1 (스택이 비어있음)
}
public void push(int item) {
if (isFull()) {
System.out.println("스택이 가득 찼습니다!");
return;
}
arr[++top] = item;
System.out.println(item + "를 스택에 추가했습니다.");
}
public int pop() {
if (isEmpty()) {
System.out.println("스택이 비어있습니다!");
return -1;
}
System.out.println(arr[top] + "를 스택에서 제거했습니다.");
return arr[top--];
}
// 스택의 맨 위 데이터 확인 (Peek)
public int peek() {
if (isEmpty()) {
System.out.println("스택이 비어있습니다!");
return -1;
}
return arr[top];
}
public boolean isEmpty() {
return top == -1;
}
public boolean isFull() {
return top == capacity - 1;
}
}
public class Main {
public static void main(String[] args) {
Stack stack = new Stack(5);
stack.push(10);
stack.push(20);
stack.push(30);
stack.push(40);
stack.push(50);
// 스택이 가득 찬 상태에서 다시 push 시도
stack.push(60); // "스택이 가득 찼습니다!" 출력됨
// 데이터 확인
System.out.println("스택의 맨 위 값: " + stack.peek()); // 50
// 데이터 제거
stack.pop();
stack.pop();
System.out.println("스택의 맨 위 값: " + stack.peek()); // 30
}
}
O(n) 삽입, 삭제 : O(1)
선입선출(FIFO) 성질을 가진 자료구조LinkedList로 구현 (Array도 가능)O(n)O(1) import java.util.LinkedList;
import java.util.NoSuchElementException;
class Queue {
private LinkedList<Integer> queue;
public Queue() {
queue = new LinkedList<>();
}
public void enqueue(int item) {
queue.addLast(item);
System.out.println(item + "를 큐에 삽입했습니다.");
}
public int dequeue() {
if (isEmpty()) {
throw new NoSuchElementException("큐가 비어있습니다!");
}
int removedItem = queue.removeFirst();
System.out.println(removedItem + "를 큐에서 제거했습니다.");
return removedItem;
}
public boolean isEmpty() {
return queue.isEmpty();
}
public int peek() {
if (isEmpty()) {
throw new NoSuchElementException("큐가 비어있습니다!");
}
return queue.getFirst();
}
}
public class Main {
public static void main(String[] args) {
Queue queue = new Queue();
queue.enqueue(10);
queue.enqueue(20);
queue.enqueue(30);
queue.enqueue(40);
System.out.println("큐의 첫 번째 값: " + queue.peek()); // 10
queue.dequeue(); // 10 제거
queue.dequeue(); // 20 제거
// 다시 데이터 확인 (Peek)
System.out.println("큐의 첫 번째 값: " + queue.peek()); // 30
System.out.println("큐가 비었나요? " + queue.isEmpty()); // false
}
}
그런데 만약, 들어온 순서에 의한 처리가 아니라 더 중요한 작업부터 처리해야 하는 경우라면? 예를 들어, 긴급 보안 점검이나 시스템 요청 같은 경우 스택이나 큐로 처리할 경우 해당 요청이 지연되는 문제가 발생할 수 있다. 이러한 상황에는 우선순위 큐를 사용해서 빠르게 처리할 수 있다.
비선형 자료구조O(1) O(log n) import java.util.PriorityQueue;
class PriorityQueueExample {
public static void main(String[] args) {
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
priorityQueue.add(30);
priorityQueue.add(10);
priorityQueue.add(20);
System.out.println("가장 높은 우선순위 요소: " + priorityQueue.peek()); // 10
priorityQueue.poll(); // 10 제거
System.out.println("다음 우선순위 요소: " + priorityQueue.peek()); // 20
}
}
| Stack | Queue | Priority Queue | |
|---|---|---|---|
| 특징 | LIFO | FIFO | 우선순위에 따라 처리 |
| 구현 형태 | Array, LinkedList | LinkedList, Array | Heap (Min-Heap, Max-Heap) |
| 사용 영역 | 뒤로가기, 메모리 영역 | CPU 스케줄링, Ready Queue, 프린터 큐 | 작업 스케줄링, 네트워크 관리 |
| 시간 복잡도 | 삽입/삭제: O(1) 탐색: O(n) | 삽입/삭제: O(1) 탐색: O(n) | 삽입/삭제: O(log n) 탐색: O(1) |