원형 큐는 선형 큐를 보완하여 Rear를 다시 맨 앞으로 배치 시키거나
Front도 동일한 방법을 사용하여 계속 배열 내부를 돌고 돌며 공간을 사용할 수 있도록 한 개념이다.
- 원형 큐도 배열이지만 원형큐를 사용하면 이 사진과 같이 원을 빙글빙글 도는 느낌으로 사용한다.
완성된 코드는 맨 아래에 있다.
Rear와 Front는 1씩 증가시켜서 이동하면 장땡이다.
그렇다면 배열의 맨 끝으로 간 Rear와 Front를 다시 앞으로 당겨오는 방법은 무엇일까?
Rear = (Rear+1)%n;
(n == 배열 길이)
Rear(Front)가 맨 끝에 있을 때만이 아니라 그냥 Rear(Front)의 움직임을 위 수식으로 하면된다.
Rear의 위치가 2, 배열 전체 길이가 3이라고 가정하고 설명해보자. 위 수식에 대입해보면
Rear = (2+1)%3
Rear = 3%3
결국 Rear에는 0이 대입되고 배열의 0번째 칸으로 이동하게된다.
Front도 동일한 방법으로 무한으로 순회할 수 있다.
Front == (Rear+1)%배열길이
Front와 Rear의 한 칸 더 진행한 위치가 같을 때 꽉 차있는 것이다.
- 이 그림에서도 Rear가 한 칸 더 진행하면 Front와 같아진다. (원형 큐에서는 전체 길이보다 한 칸 덜 쓴다.)
임의의 상황에서 삽입을 진행해본다.
삽입을 하기 위해서는 현재 큐가 꽉 차있는지 확인해야한다.
Front == (Rear+1)%배열길이
Front == (Rear+1)%8
의 값이 false이니 꽉 차있지 않으므로 삽입을 진행했다.Front == (Rear+1)%8
의 값이 true이니 꽉 차있으므로 삽입을 진행할 수 없다.Front == Rear
맨 처음에 원소가 없을 때 Front와 Rear가 같은 곳에 위치한다. 그러해서 Front와 Rear가 같으면 비어있는 것이다.
- 처음에는 같은 곳에서 시작한다.
추출을 하기 위해서는 현재 큐가 비어있는지 확인해야 한다.
Front == Rear
Front == Rear
의 값이 false라서 비어있지 않으므로 추출이 가능하다.Front == Rear
의 값이 true라서 비어있으므로 추출이 불가능하다.주의 : 원형 큐는 전체 길이보다 1칸 덜 씁니다.
public class CircularQueue<T>
{
private T[] values;
private int length;
private int front = 0;
private int rear = 0;
public CircularQueue(int length)
{
values = new T[length];
this.length = length;
}
public void Enqueue(T data)// 요소 삽입
{
if (IsFull())
{
Console.WriteLine("꽉 참");
return;
}
values[rear++] = data;
}
public T Dequeue()// 요소 추출
{
if (IsEmpty())
throw new InvalidOperationException("큐가 비어있음");
return values[front++];
}
public bool IsFull()
{ return front == (rear+1)% length; }
public bool IsEmpty()
{ return front == rear; }
public void Print()
{
int i = front;
while(i != rear)
{
Console.Write(values[i] + " ");
i = (i + 1) % length;
}
}
}
Enqueue, Dequeue 관련된 것은 위에서 설명되어 있으므로 Print 메서드를 설명한다.
i
에 초기 값을 front를 준다.i
도 i = (i + 1) % length;
를 진행하며 한 칸씩 움직인다.