- enQueue (add) : 큐의 맨 뒤에 새로운 요소 추가
- deQueue (remove) : 큐의 맨 앞의 요소 삭제
- front : 처음 부분
- rear : 마지막 부분
-> 큐에서 삽입과 삭제를 거듭하게 되면 새 item들은 뒤에 삽입되고 삭제는 앞에서 일어나기 때문데 큐의 item들이 배열의 오른쪽으로 편중되는 문제 발생!
1) 큐의 item들을 배열의 앞부분으로 이동 -> 수행시간이 큐에 들어있는 item의 수에 비례한다는 단점
2) 배열을 원형으로, 즉, 배열의 마지막 원소가 첫 원소에 맞닿아 있다고 여김
새 item 삽입 후
연속된 삭제 연산 수행 시 큐의 마지막 item을 삭제한 후 큐가 empty임에도 rear은 삭제된 item을 가리키고 있다.
-> 삭제할 때마다 조건 검사하는 것은 효율성 저하
empty가 되면 front == rear이 된다
public class ArrayQueue <E>{
private E[] q; // 큐를 위한 배열
private int front, rear, size;
public ArrayQueue() { // 생성자
q = (E[])new Object[2]; // 초기에 크기가 2인 배열 생성
front = rear = size = 0;
}
// size(), isEmpty(), add(), remove(), resize() 메소드
}
public void add (E newItem){
// 비어있는 원소가 1개뿐인 경우(큐가 full)
if((rear+1)%q.length == front) // (rear+1)%q.length : rear 다음 원소의 인덱스
resize(2*q.length); // 큐의 크기를 2배로 확장
rear = (rear+1) % q.length;
q[rear] = newItem; // 새 항목을 add
size++;
}
데이터의 마지막 부분에 데이터 삽입이 일어나므로 rear 다음인 rear+1 위치에 데이터를 삽입한다.
public E remove(){
if(isEmpty()) throw new NoSuchElementException(); // 언더플로우시 프로그램 정지
front = (front+1) % q.length;
E item = q[front];
q[front] = null;
size--;
if(size > 0 && size == q.length/4) // 큐의 항목수가 배열 크기의 1/4가 되면
resize(q.length/2); // 큐를 1/2 크기로 축소
return item;
}
가장 먼저 들어온 데이터인 맨 앞 요소를 삭제한다. front가 가리키는 요소인 front+1이 null로 삭제되고 front는 front+1이 된다.
큐에 대한 삽입, 삭제 연산 후 큐의 내용을 출력해보았다. front는 빨간색 박스, rear은 파란색 박스로 표시하였다.
public class ListQueue <E>{
private Node<E> front, rear;
private int size;
public ListQueue() {
front = rear = null;
size = 0;
}
// size(), isEmpty(), add(), remove() 메소드
}
public void add(E newItem){
Node newNode = new Node(newItem, null);
if (isEmpty()) front = newNode;
else rear.setNext(newNode);
rear = newNode;
size++;
}
새 item을 큐의 뒤인 rear에 삽입한다. rear가 참조하는 노드의 next가 새로운 노드를 가리키도록하고 그 노드를 rear가 가리키게 한다.
public E remove() {
// 언더플로우 발생 시 프로그램 정지
if(isEmpty()) throw new NoSuchElementException();
// front가 가리키는 노드의 항목을 frontItem에 저장
E frontItem = front.getItem();
// front가 front 다음 노드를 가리키게 한다
front = front.getNext();
// 큐가 empty면 rear = null
if(front==null) rear = null;
size--;
return frontItem;
}
큐의 앞의 item을 삭제한다. front가 가리키고 있는 노드의 item을 리턴하고 그 노드의 next 노드를 front가 참조하도록 한다.
1) 스크롤(Scroll)
2) 웹 브라우저의 방문 기록 등
큐 자료구조와 같이 front가 실제 가장 앞에 있는 item의 앞 원소를 가리킨다.
rear가 가리키는 노드의 이전 노드의 레퍼런스를 알아야 삭제가 가능하기 때문에 이중연결리스트로 구현하는 것이 더 편리하다.