큐 (Queue)

    • 가장 먼저 들어간 자료가 가장 먼저 나오는 자료구조
    • 먼저 들어온 데이터가 먼저 나가는 선입선출(FIFO: First-In First-Out)의 특성을 갖는 자료구조

    후단 (rear) vs 전단 (front)

    • 후단: 삽입이 일어나는 곳
    • 전단: 삭제가 일어나는 곳

    큐의 사용 예제

    • 컴퓨터의 빠른 CPU와 속도가 상대적으로 느린 주변장치(프린터)들 사이의 시간이나 속도 차이를 극복하기 위한 임시 기억 장치로 사용된다.

    큐의 연산

    • enqueue(e): 새로운 요소 e를 큐의 맨 뒤에 추가; 포화 상태인 경우 오버플로 발생.
    • dequeue(): 큐의 맨 앞에 있는 요소를 꺼내서 반환; 공백 상태인 경우 언더플로 발생.
    • isEmpty(): 큐가 비어있는지 검사
    • isFull(): 큐가 가득 차있는지 검사
    • peek(): 큐의 맨 앞에 있는 요소를 삭제하지 않고 반환
    • size(): 큐에 들어있는 전체 요소의 수를 반환

    선형 큐

    • 용령이 5인 큐에 A~E까지 가득차있고 2번의 삭제를 순서대로 수행헀다.
    • 여기서 더 삽입하려면, 큐의 앞부분에 공간이 있는데로 rear인 후단을 증가시킬 수 없으므로 삽입 불가능.
    • 따라서, 큐의 요소들을 모두 최대한 앞으로 옮겨, 후단에 공간을 확보한 다음 삽입해야된다.
    • 동작을 이해하기에는 쉬우나, 요소들의 이동이 필요하므로 효율적이지 않다.

    원형 큐

    • 인덱스인 rear 후단과 front 전단을 원형으로 회전시키는 개념
    • 이를 테면, enqueue([요소])가 호출되면 rear 후단을 시계 방향으로 1칸 회전시키고 그 위치에 [요소]를 저장하는 것.
    • 시계방향의 회전 구현: front나 rear가 계속 증가하다가 용량이 같아지면 인덱스 0으로 만들기
    • 전단 회전: front ← (front+1) % capacity
    • 후단 회전: rear ← (rear+1) % capacity

    링 버퍼(ring buffer)

    • 오래된 자료를 버리고 항상 최근의 자료를 유지하는 용도로 사용.
    • 이를 테면, 최대 7개의 요소를 저장할 수 있는 원형 큐에 7개 이상의 자료들이 연속적으로 입력되었을 때,
      가장 최근에 들어온 7개만 저장되도록 하고 오래된 데이터는 버리는 것.
    • 기존의 원형인 큐에서는 포화상태일시, 산입연산을 추가로 수행하면 오버플로가 발생하나
      링 버퍼에서는 원형 큐의 enqueue 함수 작동방식을 약간 수정하여 포화 상태와 상관없이 항상 삽입 가능.
    • 즉, 가장 오래된 데이터를 삭제해서 큐를 계속 포화 상태로 유지.
    • 프로세스
    1. 공백 상태 (capacity=8)
    2. 공백 상태에서 7개의 요소를 삽입하면 포화 상태가 됨
    3. 포화 상태에서 새로운 데이터 7을 삽입하면 가장 오래된 요소 0이 삭제됨
    4. 같은 방법으로 8을 삽입하게 된다면, 가장 오래된 요소 1이 삭제됨

    덱 (Deque)

    • double-ended queue
    • 전단과 후단에서 모두 삽입과 삭제 가능한 큐
    • 그러나 여전히 중간에 삽입하거나 삭제하는 것은 허용하지 않음

    덱의 연산

    • addFront(e): 새로운 요소 e를 전단에 추가
    • addRear(e): 새로운 요소 e를 후단에 추가
    • deleteFront(): 덱의 전단 요소를 꺼내서 반환
    • deleteRear(): 덱의 후단 요소를 꺼내서 반환
    • getFront(): 덱의 전단 요소를 삭제하지 않고 반환
    • getRear(): 덱의 후단 요소를 삭제하지 않고 반환
    • isEmpty(): 덱이 비어있는지 검사
    • isFull(): 덱이 가득 차있는지 검사
    • size(): 덱에 들어있는 전체 요소의 수를 반환

    덱의 연산 vs 스택의 연산

    • 덱의 addRear, deleteFront, getFront 연산은 각각 큐의 enqueue, dequeue, peek 연산과 동일하다
    • 덱의 후단(rear)을 스택의 상단(top)으로 사용한다면,
      덱의 addRear, deleteRear, getRear 연산은 스택의 push, pop, peek 연산과 정확히 동일하다.

    덱의 deleteRear, addFront 연산

    • 원형 큐의 enqueue나 dequeue 연산과는 달리 인덱스를 하나씩 줄여야하는데,
      이것은 반시계 방향 회전을 의미한다.
    • 이를 위한 인덱스 처리는 나머지 연산을 이용해 간결히 가능
    • 전단 회전(반시계 방향): front ← (front-1+capacity) % capacity
    • 후단 회전(반시계 방향): rear ← (rear-1+capacity) % capacity

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다