# ํ (Queue)
written by sohyeon, hyemin ๐ก
# 1. ํ๋?
ํ
๋ ๋ฐ์ดํฐ๋ฅผ ์ผ์์ ์ผ๋ก ์์ ๋๊ธฐ ์ํ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
์
์ถ๋ ฅ ์์๋ ๊ฐ์ฅ ๋จผ์ ๋ฃ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฅ ๋จผ์ ๊บผ๋ด๋ ์ ์
์ ์ถ
๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฅธ๋ค.
์ํ์์ ๋ณผ ์ ์๋ ํ์ ์์๋ก๋,
์ํ ์ฐฝ๊ตฌ์์์ ์ฐจ๋ก๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋๊ธฐ, ๋งํธ ๊ณ์ฐ์ ์ํด ๊ธฐ๋ค๋ฆฌ๋ ๋๊ธฐ์ด์ ๋ค ์ ์๋ค.
# 2. ๋ฐฐ์ด๋ก ํ ๋ง๋ค๊ธฐ
ํ๋ ๋ฐฐ์ด์ ์ฌ์ฉํ์ฌ ๊ตฌํํ ์ ์๋ค. ๋ฐฐ์ด์ ์ฌ์ฉํ ํ์ ๋ํ ์์์ด๋ค.
# 2-1. ํด๋์ค์ ์์ฑ์
public class IntQueue{
private int max; // ํ์ ์ฉ๋
private int front; // ๋งจ ์ ์ปค์
private int rear; // ๋งจ ๋ค ์ปค์
private int num; // ํ์ฌ์ ๋ฐ์ดํฐ ์
private int[] que; // ํ์ ๋ณธ์ฒด
// ์คํํ ๋ ์์ธ๏ผํ๊ฐ ๋น์ด ์์
public class EmptyIntQueueException extends RuntimeException {
public EmptyIntQueueException() {
}
}
// ์คํํ ๋ ์์ธ๏ผํ๊ฐ ๊ฐ๋ ์ฐธ
public class OverflowIntQueueException extends RuntimeException {
public OverflowIntQueueException() {
}
}
// ์์ฑ์
public IntQueue(int capacity) {
num = front = rear = 0;
max = capacity;
try {
que = new int[max]; // ํ ๋ณธ์ฒด์ฉ ๋ฐฐ์ด์ ์์ฑ
} catch (OutOfMemoryError e) { // ์์ฑํ ์ ์์ต๋๋ค.
max = 0;
}
}
}
์์ฑ ์ ํ๋ ๋น์ด ์์ผ๋ฏ๋ก ์คํ ํฌ์ธํฐ num, front, rear ๋ชจ๋ 0์ผ๋ก ํ๋ค.
๋งค๊ฐ๋ณ์ capacity๋ก ์ ๋ฌ๋ฐ์ ๊ฐ์ ์คํ ์ฉ๋์ ๋ํ๋ด๋ max์ ๋ณต์ฌํ๊ณ
์์์๊ฐ max์ธ ๋ฐฐ์ด que์ ๋ณธ์ฒด๋ฅผ ์์ฑํ๋ค.
# 2-2. ๋ฉ์๋
# 1) ๋ฐ์ดํฐ ์ถ๊ฐ, ์ญ์
# ๋ฐ์ดํฐ ์ถ๊ฐ - enque
rear์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ์์ ๋ค์์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ ๋ฉ์๋์ด๋ค.
ํ๊ฐ ๊ฐ๋์ฐจ์ enque ํ ์ ์๋ ๊ฒฝ์ฐ ์์ธ OverflowIntQueueException
์ throwํ๋ค.
์ ๋ฌ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ ์ ์์ผ๋ฉด que[rear++]
์ ์ ์ฅํ๊ณ , ํ์ฌ ๋ฐ์ดํฐ ์ num์ ์ฆ๊ฐ ์ํจ๋ค.
๋ฉ์๋์ ๋ฐํ๊ฐ์ enqueํ ๊ฐ์ด๋ค.
public int enque(int x) throws OverflowIntQueueException {
if (num >= max)
throw new OverflowIntQueueException(); // ํ๊ฐ ๊ฐ๋ ์ฐธ
que[rear++] = x;
num++;
if (rear == max)
rear = 0;
return x;
}
# ๋ฐ์ดํฐ ์ญ์ - deque
front์ ์์นํ ๋งจ ์์ ์์๋ฅผ ๊บผ๋ธ ๋ค์ ๊ทธ ์ดํ์ ์์๋ฅผ ์์ผ๋ก ์ฎ๊ธฐ๋ ๋ฉ์๋์ด๋ค.
ํ๊ฐ ๋น์ด ์์ด deque ํ ์์๊ฐ ์๋ ๊ฒฝ์ฐ ์์ธ EmptyIntQueueException
์ throwํ๋ค.
public int deque() throws EmptyIntQueueException {
if (num <= 0)
throw new EmptyIntQueueException(); // ํ๊ฐ ๋น์ด ์์
int x = que[front++];
num--;
if (front == max)
front = 0;
return x;
}
# 3) ๊ทธ ์ธ
peek : front์ ์๋ ๊ฐ์ ๋ณด๋ ๋ฉ์๋์ด๋ค.
indexOf : ๋ฐฐ์ด que์ x์ ๊ฐ์ ๊ฐ์ ๋ฐ์ดํฐ๊ฐ ํฌํจ๋์ด ์๋์ง,
ํฌํจ๋์ด ์๋ค๋ฉด ๋ฐฐ์ด์ ์ด๋์ ๋ค์ด ์๋์ง๋ฅผ ์กฐ์ฌํ๋ ๋ฉ์๋์ด๋ค.clear : ํ์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๋ ๋ฉ์๋
capacity : ์ฉ๋์ ํ์ธํ๋ ๋ฉ์๋
size : ํ์ฌ ํ์ ์์ฌ์๋ ๋ฐ์ดํฐ ์๋ฅผ ๋ฐํํ๋ ๋ฉ์๋
isEmpty : ํ๊ฐ ๋น์ด ์๋์ง ๊ฒ์ฌํ๋ ๋ฉ์๋
isFull : ํ๊ฐ ๊ฐ๋ ์ฐผ๋์ง ๊ฒ์ฌํ๋ ๋ฉ์๋
// ํ์์ ๋ฐ์ดํฐ๋ฅผ ํผํฌ(๋จธ๋ฆฌ๋ฐ์ดํฐ๋ฅผ ์ดํด๋ด)
public int peek() throws EmptyIntQueueException {
if (num <= 0)
throw new EmptyIntQueueException(); // ํ๊ฐ ๋น์ด ์์
return que[front];
}
// ํ์์ x๋ฅผ ๊ฒ์ํ์ฌ index(์ฐพ์ง ๋ชปํ๋ฉด -1)๋ฅผ ๋ฐํ
public int indexOf(int x) {
for (int i = 0; i < num; i++) {
int idx = (i + front) % max;
if (que[idx] == x) // ๊ฒ์์ฑ๊ณต
return idx;
}
return -1; // ๊ฒ์์คํจ
}
// ํ๋ฅผ ๋น์
public void clear() {
num = front = rear = 0;
}
// ํ์ ์ฉ๋์ ๋ฐํ
public int capacity() {
return max;
}
// ํ์ ์์ธ ๋ฐ์ดํฐ ์๋ฅผ ๋ฐํ
public int size() {
return num;
}
// ํ๊ฐ ๋น์ด ์๋๊ฐ?
public boolean isEmpty() {
return num <= 0;
}
// ํ๊ฐ ๊ฐ๋ ์ฐผ๋๊ฐ?
public boolean isFull() {
return num >= max;
}
// ํ ์์ ํฐ(์ดํฐ๋ฅผ ๋จธ๋ฆฌโ๊ผฌ๋ฆฌ์ ์ฐจ๋ก๋ก ๋ํ๋
public void dump() {
if (num <= 0)
System.out.println("ํ๊ฐ ๋น์์ต๋๋ค.");
else {
for (int i = 0; i < num; i++)
System.out.print(que[(i + front) % max] + " ");
System.out.println();
}
}
# 3. ๋ง ๋ฒํผ๋ก ํ ๋ง๋ค๊ธฐ
๋ง ๋ฒํผ
๋ ๋ฐฐ์ด์ ์ฒ์์ด ๋๊ณผ ์ฐ๊ฒฐ๋์ด์๋ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
๋ง ๋ฒํผ
๋ฅผ ํ์ฉํ๋ฉด ๋ฐฐ์ด์์๋ฅผ ์์ชฝ์ผ๋ก ์ฎ๊ธฐ๋ ์์
์ด ๋ถํ์ํ๋ค.
๋
ผ๋ฆฌ์ ์ผ๋ก ์ฒซ๋ฒ์งธ ์์์ ๋ง์ง๋ง ์์๋ฅผ ์๋ณํ๊ธฐ ์ํด front
์ rear
๋ณ์๊ฐ ์กด์ฌํ๋ค.
- front : ๋งจ ์ฒ์ ์์์ ์ธ๋ฑ์ค
- rear : ๋งจ ๋ ์์์ ํ๋ ๋ค์ ์ธ๋ฑ์ค (๋ค์ ์์๋ฅผ ์ธํํ ์์น๋ฅผ ๋ฏธ๋ฆฌ ์ง์ )
# 3-1. ํด๋์ค์ ์์ฑ์
public class IntQueue{
private int max; // ํ์ ์ฉ๋
private int front; // ์ฒซ๋ฒ์งธ ์์ ์ปค์
private int rear; // ๋ง์ง๋ง ์์ ์ปค์
private int num; // ํ์ฌ ๋ฐ์ดํฐ ์
private int[] que; // ํ ๋ณธ์ฒด
// ์คํ ์ ์์ธ: ํ๊ฐ ๋น์ด ์์
public class EmptyIntQueueException extends RuntimeException{
public OverflowIntQueueException(){}
}
// ์คํ ์ ์์ธ : ํ๊ฐ ๊ฐ๋ ์ฐจ ์์
public class OverflowIntQueueException extends RuntimeException{
public OverflowIntQueueException(){}
}
// ์์ฑ์
public IntQueue(int capacity){
num = front = rear = 0;
max = capacity;
try{
que = new int[max];
} catch(OutOfMemoryError e){
max = 0;
}
}
}
front
์rear
์ ๊ฐ์ด ๊ฐ์ ๋ ํ์ ์ํ๋ ๋น์ด์๊ฑฐ๋ ๊ฐ๋์ฐฌ ์ํ์ด๋ค.
์ด ์กฐ๊ฑด๋ง์ผ๋ก ๊ตฌ๋ถ์ ํ ์ ์๋ค.front
์rear
์ ๊ฐ์ด ๊ฐ์ ๊ฒฝ์ฐ, ํ์ ์ํ๋ฅผ ๊ตฌ๋ถํ๊ธฐ ์ํดnum
๋ณ์๋ฅผ ํ์ฉ
ํ๊ฐ ๋น์์ ๋num
์ 0์ด๊ณ ํ๊ฐ ๊ฐ๋ ์ฐผ์๋num
์ max์ ๊ฐ๊ณผ ๊ฐ๋ค.
# 3-2. ๋ฉ์๋
# 1) enque
ํ์ ๋ฐ์ดํฐ๋ฅผ ์ธํํ๊ณ ์ธํ๋ ๊ฐ์ ๋ฐํํ๋ ๋ฉ์๋์ด๋ค.
rear์ ์์น์ ์์๋ฅผ ์ถ๊ฐํ๊ณ rear์ num๊ฐ์ 1๋งํผ ์ฆ๊ฐํ๋ค.
์ธํํ๊ธฐ ์ rear์ ๊ฐ์ด max-1 ๊ฐ์ด๋ผ๋ฉด enque ์ํ ํ rear๊ฐ์ด max์ ๊ฐ์์ง๊ฒ ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด rear๊ฐ์ด 1๋งํผ ์ฆ๊ฐํ์ ๋ max์ ๊ฐ์์ง๋ ๊ฒฝ์ฐ rear๋ฅผ ๋ฐฐ์ด์ ์ฒ์์ธ 0์ผ๋ก ๋ณ๊ฒฝํ๋ค.
public int enque(int x) throws OverflowIntQueueException {
if(num>=max)
throw new OverflowIntQueueException();
que[rear++] = x;
num++;
if(rear == max)
rear = 0;
return x;
}
# 2) deque
ํ์์ ๋ฐ์ดํฐ๋ฅผ ๋ํํ๊ณ ๊ทธ ๊ฐ์ ๋ฐํํ๋ ๋ฉ์๋์ด๋ค.
front์ ์ ์ฅ๋ ๊ฐ์ ๊บผ๋ด๊ณ front๊ฐ์ 1๋งํผ ์ฆ๊ฐํ ๋ค์ num์ 1๋งํผ ๊ฐ์์ํจ๋ค.
๋ํํ๊ธฐ ์ front๊ฐ์ด ๋ฐฐ์ด์ ๋์ด๋ผ๋ฉด ๋ํ ์ํ ์ดํ์ front๊ฐ์ด max๊ฐ ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด front๊ฐ์ด 1๋งํผ ์ฆ๊ฐํ์ ๋ max์ ๊ฐ์์ง๋ฉด front๊ฐ์ ๋ฐฐ์ด์ ์ฒ์์ธ 0์ผ๋ก ๋ณ๊ฒฝํ๋ค.
public int deque() throws EmptyIntQueueException{
if(num<=0)
throw new EmptyIntQueueException();
int x = que[front++];
num--;
if(front == max)
front = 0;
return x;
}
# 3) ๊ทธ ์ธ
// ํ์์ ๋ฐ์ดํฐ๋ฅผ ํผํฌ (ํ๋ฐํธ ๋ฐ์ดํฐ๋ฅผ ๋ค์ฌ๋ค๋ด)
public int peek() throws EmptyIntQueueException {
if (num <= 0)
throw new EmptyIntQueueException(); // ํ๊ฐ ๋น์ด ์์
return que[front];
}
// ํ์์ x๋ฅผ ๊ฒ์ํ์ฌ ์ธ๋ฑ์ค(์ฐพ์ง ๋ชปํ๋ฉด โ1)๋ฅผ ๋ฐํ
public int indexOf(int x) {
for (int i = 0; i < num; i++) {
int idx = (i + front) % max;
if (que[idx] == x) // ๊ฒ์ ์ฑ๊ณต
return idx;
}
return -1; // ๊ฒ์ ์คํจ
}
// ํ๋ฅผ ๋น์
public void clear() {
num = front = rear = 0;
}
// ํ์ ์ฉ๋์ ๋ฐํ
public int capacity() {
return max;
}
// ํ์ ์์ฌ ์๋ ๋ฐ์ดํฐ ์๋ฅผ ๋ฐํ
public int size() {
return num;
}
// ํ๊ฐ ๋น์ด ์๋์?
public boolean isEmpty() {
return num <= 0;
}
// ํ๊ฐ ๊ฐ๋ ์ฐผ๋์?
public boolean isFull() {
return num >= max;
}
// ํ ์์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ํ๋ฐํธ โ ๋ฆฌ์ด ์์ผ๋ก ์ถ๋ ฅ
public void dump() {
if (num <= 0)
System.out.println("ํ๊ฐ ๋น์ด ์์ต๋๋ค.");
else {
for (int i = 0; i < num; i++)
System.out.print(que[(i + front) % max] + " ");
System.out.println();
}
}
# 4. ๋ฑ(์๋ฐฉํฅ ๋๊ธฐ์ด, deque/double ended queue)
์์๊ณผ ๋ ์ง์ , ์์ชฝ์์ ๋ฐ์ดํฐ๋ฅผ ์ธํํ๊ฑฐ๋ ๋ํํ๋ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
# ๋ฑ ๋ง๋ค๊ธฐ
public class IntDeque {
private int max; // ๋ฑ(deck)์ ์ฉ๋
private int num; // ํ์ฌ์ ๋ฐ์ดํฐ ์
private int front; // ๋งจ ์ ์ปค์
private int rear; // ๋งจ ๋ค ์ปค์
private int[] que; // ๋ฑ(deck)์ ๋ณธ์ฒด
// ์คํํ ๋ ์์ธ๏ผํ๊ฐ ๋น์ด ์์
public class EmptyIntDequeException extends RuntimeException {
public EmptyIntDequeException() {
}
}
// ์คํํ ๋ ์์ธ๏ผํ๊ฐ ๊ฐ๋ ์ฐธ
public class OverflowIntDequeException extends RuntimeException {
public OverflowIntDequeException() {
}
}
// ์์ฑ์
public IntDeque(int capacity) {
num = front = rear = 0;
max = capacity;
try {
que = new int[max]; // ๋ฑ(deck)๋ณธ์ฒด์ฉ ๋ฐฐ์ด์ ์์ฑ
} catch (OutOfMemoryError e) { // ์์ฑํ ์ ์์ต๋๋ค
max = 0;
}
}
// ๋ฑ(deck)์ ๋ฐ์ดํฐ๋ฅผ ๋จธ๋ฆฌ์ชฝ๋ถํฐ ์ธํ
public int enqueFront(int x) throws OverflowIntDequeException {
if (num >= max)
throw new OverflowIntDequeException(); // ๋ฑ(deck)์ด ๊ฐ๋ ์ฐธ
num++;
if (--front < 0)
front = max - 1;
que[front] = x;
return x;
}
// ๋ฑ(deck)์ ๋ฐ์ดํฐ๋ฅผ ๊ผฌ๋ฆฌ์ชฝ๋ถํฐ ์ธํ
public int enqueRear(int x) throws OverflowIntDequeException {
if (num >= max)
throw new OverflowIntDequeException(); // ๋ฑ(deck)์ ๊ฐ๋ ์ฐธ
que[rear++] = x;
num++;
if (rear == max)
rear = 0;
return x;
}
// ๋ฑ(deck)์ ๋จธ๋ฆฌ๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ํ
public int dequeFront() throws EmptyIntDequeException {
if (num <= 0)
throw new EmptyIntDequeException(); // ๋ฑ(deck)์ด ๋น์ด ์์
int x = que[front++];
num--;
if (front == max)
front = 0;
return x;
}
// ๋ฑ(deck)์ ๊ผฌ๋ฆฌ๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ํ
public int dequeRear() throws EmptyIntDequeException {
if (num <= 0)
throw new EmptyIntDequeException(); // ๋ฑ(deck)์ด ๋น์ด ์์
num--;
if (--rear < 0)
rear = max - 1;
return que[rear];
}
// ๋ฑ(deck)์ ๋จธ๋ฆฌ๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ํผํฌ(๋จธ๋ฆฌ๋ฐ์ดํฐ๋ฅผ ์ดํด๋ด)
public int peekFront() throws EmptyIntDequeException {
if (num <= 0)
throw new EmptyIntDequeException(); // ๋ฑ(deck)์ด ๋น์ด ์์
return que[front];
}
// ๋ฑ(deck)์ ๊ผฌ๋ฆฌ๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ํผํฌ(๊ผฌ๋ฆฌ๋ฐ์ดํฐ๋ฅผ ์ดํด๋ด)
public int peekRear() throws EmptyIntDequeException {
if (num <= 0)
throw new EmptyIntDequeException(); // ๋ฑ(deck)์ด ๋น์ด ์์
return que[rear == 0 ? max - 1 : rear - 1];
}
// ๋ฑ(deck)์์ x๋ฅผ ๊ฒ์ํ์ฌ index(์ฐพ์ง ๋ชปํ๋ฉด -1)๋ฅผ ๋ฐํ
public int indexOf(int x) {
for (int i = 0; i < num; i++)
if (que[(i + front) % max] == x) // ๊ฒ์์ฑ๊ณต
return i + front;
return -1; // ๊ฒ์์คํจ
}
// ๋ฑ(deck)์์ x๋ฅผ ๊ฒ์ํ์ฌ ๋จธ๋ฆฌ๋ถํฐ ๋ช ๋ฒ ์งธ์ธ๊ฐ(์ฐพ์ง ๋ชปํ๋ฉด 0)๋ฅผ ๋ฐํ
public int search(int x) {
for (int i = 0; i < num; i++)
if (que[(i + front) % max] == x) // ๊ฒ์์ฑ๊ณต
return i + 1;
return 0; // ๊ฒ์์คํจ
}
// ๋ฑ(deck)์ ๋น์
public void clear() {
num = front = rear = 0;
}
// ๋ฑ(deck)์ ์ฉ๋์ ๋ฐํ
public int capacity() {
return max;
}
// ๋ฑ(deck)์ ์์ธ ๋ฐ์ดํฐ ์๋ฅผ ๋ฐํ
public int size() {
return num;
}
// ๋ฑ(deck)์ด ๋น์ด ์๋๊ฐ?
public boolean isEmpty() {
return num <= 0;
}
// ๋ฑ(deck)์ด ๊ฐ๋ ์ฐผ๋๊ฐ?
public boolean isFull() {
return num >= max;
}
// ๋ฑ(deck)๋ด์ ๋ฐ์ดํฐ๋ฅผ ๋จธ๋ฆฌโ๊ผฌ๋ฆฌ์ ์ฐจ๋ก๋ก ๋ํ๋
public void dump() {
if (num <= 0)
System.out.println("๋ฑ(deck)์ด ๋น์์ต๋๋ค.");
else {
for (int i = 0; i < num; i++)
System.out.print(que[(i + front) % max] + " ");
System.out.println();
}
}
}