본문 바로가기

개발지/Today I learn

[1122] 자바 - 자료구조 (Queue)

# Queue

- Queue의 정의와 구조

  ▪ 데이터를 처리하는 자료 구조 중 하나.

  ▪ 스택과 다르게 FIFO / LILO을 특징으로 가지고 있다.

  ▪ 데이터를 입력된 순서대로 처리할 때 사용한다.

  ▪ 두 개의 입출력 방향을 가지고 있으며, 데이터를 하나씩 넣고 뺀다.

 

- Queue의 장점.

  • 자료를 넣은 순서대로 꺼내서 처리할 수 있어서, 처리해야할 작업을 순서대로 처리할 때 유리.
  • 다른 자료 구조에 비해 상대적으로 빠른 속도를 가지고 있다. (삽입과 삭제 각각의 방향. 원소를 삭제하는 연산 없음)
  • 별도 라이브러리나 모듈 설치필요 X

 

- Queue의 단점

  • 중간에 데이터를 조회하거나 수정할 수 없음. (중간 데이터를 수정하기 위해서는 그 앞의 데이터를 모두 꺼내야함)
  • 크기 제한이 없어 메모리의 낭비 발생
  • iterator() 메서드가 지원되지 않음. 데이터를 순회할 때 peek() 메서드와 poll() 메서드를 사용하여 데이터를 가져와야함
  • remove() 메서드의 동작이 불명확. (큐에서 중복된 객체가 있을 때 remove를 통해 삭제되는 객체가 불명확)

 

- Queue의 사용

  • 컴퓨터 장치들은 각각 다른 처리 속도를 가지고 있다. 이런 차이를 극복하기 위해 컴퓨터는 버퍼링을 사용한다. 임시 기억 장치의 입력된 데이터를 저장해놓는데 임시 기억 장치로 Queue를 사용한다. 이를 버퍼(buffer)라고 한다. 
  • 컴퓨터의 데이터 발생은 불규칙적으로 발생하는데, 이를 처리하는 CPU는  규칙적으로 데이터를 처리한다.
  • 대표적으로 컴퓨터와 프린터 사이에 인쇄명령. 동영상 스트리밍의 버퍼링 등의 Queue의 대표적 사용 예시이다.

 

- Queue 활용 예시

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class parkingLot {
    private Queue<Integer>[] parkingFloors; 

    public parkingLot() {
        parkingFloors = new Queue[5]; 
        for (int i = 0; i < 5; i++) {
            parkingFloors[i] = new LinkedList<>(); 
        }
    }

    public void park(int carNum) {
        boolean parked = false;
        for (Queue<Integer> parkingFloor : parkingFloors) {
            if (parkingFloor.size() < 15) {
                parkingFloor.add(carNum);
                System.out.println(carNum + "가" + (Arrays.asList(parkingFloors).indexOf(parkingFloor) + 1) + "층에 주차되었습니다.");
                parked = true;
                break;
            }
        }
        if (!parked) {
            System.out.println("주차 공간이 없습니다.");
        }
    }

    public int exit() {
        int car = -1;
        for (Queue<Integer> parkingFloor : parkingFloors) {
            if (!parkingFloor.isEmpty()) {
                car = parkingFloor.poll();
                System.out.println(car + "가" + Arrays.asList(parkingFloors).indexOf(parkingFloor) + 1 + "층에서 출차되었습니다.");
                break;
            }
        }
        if (car == -1) {
            System.out.println("주차된 차량이 없습니다.");
        }
        return car;
    }

    public static void main(String[] args) {
        parkingLot parkingtower = new parkingLot();
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.println("1. 차량 입차하기");
            System.out.println("2. 차량 출차하기");
            System.out.println("3. 종료하기");
            System.out.println("원하는 작업의 번호를 입력하세요");
            int num = scanner.nextInt();
            if (num == 1) {
                System.out.println("보관할 차량의 번호를 입력하세요");
                int carNum = scanner.nextInt();
                parkingtower.park(carNum);
            } else if (num == 2) {
                parkingtower.exit();
            } else if (num == 3) {
                System.out.println("주차프로그램을 종료합니다.");
                break;
            } else {
                System.out.println("잘못된 입력입니다. 다시 입력해주세요.");
            }
            System.out.println();
        }
    }
}