Stack implementation : LinkedList
push <- constant (tail에서 넣으면 됨)
pop <- linear. (tail 을 찾을 수는 있지만, 마지막 노드를 찾으려면 n번 이동해야됨)
그래서 stack의 top을 head에 넣으면은, pop도 constant time 필요
Queue
-enqueue : constant time
-deque : constant time
Queue with array
-잘 모르겟음..
(gpt)
📌 배열 기반 Queue에서 나머지를 사용하는 이유 (Circular Queue)
배열(Array)로 Queue를 구현할 때, 나머지 연산 (%)을 사용하여 원형 큐 (Circular Queue)를 만드는 이유를 설명할게.
✅ 1. 기본적인 배열 기반 큐 (문제점)
배열을 사용해서 큐를 구현할 때, front와 rear라는 두 개의 인덱스를 사용해 요소를 추가/삭제하는 방식이야.
기본적인 enqueue() / dequeue() 구현
class ArrayQueue {
private int[] data;
private int front, rear, size;
private int capacity;
public ArrayQueue(int capacity) {
this.capacity = capacity;
this.data = new int[capacity];
this.front = 0;
this.rear = 0;
this.size = 0;
}
public void enqueue(int elem) {
if (size == capacity) {
System.out.println("Queue is full");
return;
}
data[rear] = elem;
rear++; // rear를 증가
size++;
}
public int dequeue() {
if (size == 0) {
System.out.println("Queue is empty");
return -1;
}
int value = data[front];
front++; // front를 증가
size--;
return value;
}
}
❌ 문제 발생: 빈 공간 낭비
위 코드에서는 rear와 front를 계속 증가시키면서 큐를 구현하지만, 큐가 꽉 찬 것처럼 보이지만 실제로는 비어있는 공간이 존재할 수 있음.
예제: 큐 크기 5
- enqueue(1), enqueue(2), enqueue(3), enqueue(4), enqueue(5) → rear = 5
- dequeue(), dequeue(), dequeue() → front = 3
- enqueue(6) 시도 → 공간이 남았는데도 rear == 5라서 큐가 꽉 찼다고 나옴!
[ _, _, _, 4, 5 ] (front=3, rear=5, size=2)
💡 문제점: rear가 끝까지 가면 다시 앞쪽 공간을 활용하지 못함 → 비효율적!
✅ 2. 원형 큐 (Circular Queue)로 해결
이 문제를 해결하려면 나머지 연산 (%)을 사용하여 rear와 front가 배열의 시작으로 돌아오도록 하면 돼.
rear = (rear + 1) % capacity;
front = (front + 1) % capacity;
이렇게 하면 배열을 원형(Circular)처럼 사용하여 공간을 낭비하지 않음.
🔹 원형 큐 적용 코드
class CircularQueue {
private int[] data;
private int front, rear, size;
private int capacity;
public CircularQueue(int capacity) {
this.capacity = capacity;
this.data = new int[capacity];
this.front = 0;
this.rear = 0;
this.size = 0;
}
public void enqueue(int elem) {
if (size == capacity) {
System.out.println("Queue is full");
return;
}
data[rear] = elem;
rear = (rear + 1) % capacity; // 원형으로 이동
size++;
}
public int dequeue() {
if (size == 0) {
System.out.println("Queue is empty");
return -1;
}
int value = data[front];
front = (front + 1) % capacity; // 원형으로 이동
size--;
return value;
}
}
✅ 3. 원형 큐의 동작 원리
배열 크기가 5일 때 enqueue()와 dequeue() 연산을 수행해 보자.
(1) 초기 상태
front = 0, rear = 0, size = 0
(2) enqueue(1), enqueue(2), enqueue(3), enqueue(4), enqueue(5)
data = [1, 2, 3, 4, 5]
front = 0, rear = 5 (rear = 5 % 5 = 0)
(3) dequeue(), dequeue(), dequeue() 실행
data = [_, _, _, 4, 5]
front = 3, rear = 0
(4) enqueue(6), enqueue(7), enqueue(8)
data = [6, 7, 8, 4, 5]
front = 3, rear = 3 (rear = 3 % 5 = 3)
✅ rear가 배열의 처음으로 돌아가면서 빈 공간을 재사용할 수 있음!
✅ 4. 왜 나머지 연산 (%)을 사용해야 할까?
- 배열이 끝까지 차도 다시 앞에서부터 사용할 수 있도록 함.
- 항상 rear와 front를 배열 크기 안에서 유지할 수 있음.
- O(1) 연산을 유지하면서, 추가적인 공간 낭비 없이 큐를 사용할 수 있음.
💡 결론: 원형 큐(Circular Queue)는 나머지 연산을 사용해서 공간을 재활용하고, 큐가 가득 차는 문제를 해결할 수 있도록 한다! 🚀
'미국유학 > Data Structure and Algorithm' 카테고리의 다른 글
Binary Search Tree (BSTNode) (0) | 2025.02.09 |
---|---|
2월6일 DSA (0) | 2025.02.07 |
Jan 31 Friday 2025 (1) | 2025.02.05 |
1.28 화요일 (0) | 2025.01.29 |
1/23(목) , 1/24 (금) (0) | 2025.01.29 |