공부방
LinkedList / 원형Queue 본문
원형 큐
- 초기 공백 상태
front=rear=0 - Index의 순환
- front와 rear의 위치가 배열의 마지막 인덱스인 n-1을 가리킨 후, 그 다음에는 논리적 순환을 이루어 배열의 처음 인덱스인 0으로 이동해야함
- 이를 위해 나머지 연산자 mod를 사용
- front 변수
공백 상태와 포화 상태 구분을 쉽게 하기 위해 front가 있는 자리는 사용하지 않고 항상 빈자리로 둠.
선형 큐 | 원형 큐 | |
front / rear | 가장 첫번째 원소 한 칸 앞 idx / 가장 마지막 원소 | |
초기 값 | front->-1 / rear->-1 | front->0 / rear->0 |
가장 첫번째 삽입 원소 idx | 0 | 1 |
enQueue | rear++ arr[rear]->item |
rear->(rear+1)%arr.length arr[rear]->item |
deQueue | front++ return arr[front] |
front->(front+1)%n return arr[front] |
원형 큐의 연산 과정
package test1;
//원형 큐
public class test1 {
public static int n=5;
public static int arr[]=new int[n];
public static int front=0, rear=0;
public static void main(String[] args) {
enQueue(1);
enQueue(2);
enQueue(3);
enQueue(4);
enQueue(5);//원형큐는 크기가 5인 배열이지만 front자리가 비기 때문에
//5번째 인덱스에는 합류가 불가능
System.out.println(deQueue());
System.out.println(deQueue());
System.out.println(deQueue());
System.out.println(deQueue());
System.out.println(deQueue());
//선형큐에서는 불가능하지만 원형큐에서는 가능
enQueue(6);
enQueue(7);
enQueue(8);
System.out.println(deQueue());
System.out.println(deQueue());
System.out.println(deQueue());
}
//큐가 비어 있는지
public static boolean isEmpty() {
return front==rear;//선형 큐와 같다.
}
//큐가 다 찼는지
public static boolean isFull() {
return (rear+1)%n==front;
}
//선형큐에서는 rear에 ++하고 리턴하지만 원형큐에서는 나머지 연산을 통해
//만약 크기가 4인 배열이라면 0->1 1->2 2->3 3->4 4->0로 순환할 수 있게
//나머지 연산을 추가해줘 크기를 나눈 나머지값을 front값과 비교.
//enQueue
public static void enQueue(int item) {
if (isFull()) {
System.out.println("큐가 가득 차서 더이상 원소 못 넣음");
}else {
rear=(rear+1)%n;
arr[rear]=item;
}
}
//마찬가지로 n만큼 나눈 곳을 rear로 선언하고 그곳을 enQueue
//deQueue
public static int deQueue() {
if (isEmpty()) {
System.out.println("큐가 비었음");
return -1;
}else {
front=(front+1)%n;
return arr[front];
}
}
}
//뺄 때도 n으로 나눈곳을 리턴
//
큐가 가득 차서 더이상 원소 못 넣음
1
2
3
4
큐가 비었음
-1
6
7
8
우선순위 큐의 특성
- 우선순위를 가진 항목들을 저장하는 큐
- FIFO 순서가 아니라 우선순위가 높은 순서대로 먼저 나가게 된다.
PriorityQueue 사용 방법
package test2;
import java.util.Collections;
import java.util.PriorityQueue;
//우선 순위 큐
public class test1 {
public static void main(String[] args) {
//기본값: 숫자가 작은게 우선순위가 높다.(오름차순)
PriorityQueue<Integer> pq=new PriorityQueue<>();
//1. 생성자에다가 Comparator를 만들어 넣던지,
//2. person이 Comparable을 구현하도록 한다.
pq.offer(100);
pq.offer(2);
pq.offer(31);
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
//우선순위를 뒤집으려면 생성자에다가 Comparator
pq=new PriorityQueue<>(Collections.reverseOrder());
pq.offer(100);
pq.offer(2);
pq.offer(31);
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
}
}
//
2
31
100
100
31
2
새로운 클래스에 객체 생성 후 Comparable을 implements하여 구현하는 방법
package test3;
//Comparable을 implements할 클래스 생성 후 객체 생성하고
//Override 부분에 비교를 해준다.
public class person implements Comparable<person>{
public String name;
public int age;
public person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "person [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(person o) {
//나이 순
return this.age-o.age;
//이름 순
return this.name.compareTo(o.name);
}
}
====================================================================
package test3;
import java.util.PriorityQueue;
public class test1 {
public static void main(String[] args) {
PriorityQueue<person> pq=new PriorityQueue<>();
pq.offer(new person("강현", 26));
pq.offer(new person("강현일", 27));
pq.offer(new person("강현이", 28));
pq.offer(new person("강현삼", 29));
pq.offer(new person("강현사", 30));
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
}
}
//
(나이순)
person [name=강현, age=26]
person [name=강현일, age=27]
person [name=강현이, age=28]
person [name=강현삼, age=29]
person [name=강현사, age=30]
(이름순)
person [name=강현, age=26]
person [name=강현사, age=30]
person [name=강현삼, age=29]
person [name=강현이, age=28]
person [name=강현일, age=27]
새로운 클래스에 생성자에다가 Comparator를 implements하여 구현하는 방법
package test4;
public class person{
public String name;
public int age;
public person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "person [name=" + name + ", age=" + age + "]";
}
}
============================================================
package test4;
import java.util.Comparator;
public class ageComparator implements Comparator<person>{
@Override
public int compare(person o1, person o2) {
return o1.age-o2.age;
}
}
================================================================
package test4;
import java.util.Comparator;
public class nameComparator implements Comparator<person>{
@Override
public int compare(person o1, person o2) {
return o1.name.compareTo(o2.name);
}
}
===================================================================
package test4;
import java.util.Comparator;
import java.util.PriorityQueue;
public class test1 {
public static void main(String[] args) {
PriorityQueue<person> pq=new PriorityQueue<>(new nameComparator());
PriorityQueue<person> pq=new PriorityQueue<>(new ageComparator());
pq.offer(new person("강현", 26));
pq.offer(new person("강현일", 27));
pq.offer(new person("강현이", 28));
pq.offer(new person("강현삼", 29));
pq.offer(new person("강현사", 30));
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
}
}
//
person [name=강현, age=26]
person [name=강현사, age=30]
person [name=강현삼, age=29]
person [name=강현이, age=28]
person [name=강현일, age=27]
person [name=강현, age=26]
person [name=강현일, age=27]
person [name=강현이, age=28]
person [name=강현삼, age=29]
person [name=강현사, age=30]
무명 클래스로 한 클래스 안에서 객체를 생성 후 비교하는 방법
package test4;
import java.util.Comparator;
import java.util.PriorityQueue;
public class test1 {
public static void main(String[] args) {
//무명 클래스: 이름이 없는 클래스, 객체를 단 한번만 생성
PriorityQueue<person> pq=new PriorityQueue<>(new Comparator<person>() {
@Override
public int compare(person o1, person o2) {
return o1.age-o2.age;
}
});
pq.offer(new person("강현", 26));
pq.offer(new person("강현일", 27));
pq.offer(new person("강현이", 28));
pq.offer(new person("강현삼", 29));
pq.offer(new person("강현사", 30));
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
}
}
//
person [name=강현, age=26]
person [name=강현일, age=27]
person [name=강현이, age=28]
person [name=강현삼, age=29]
person [name=강현사, age=30]
람다 표현식 / 이름이 같을 때 나이순으로 비교하는 방법도 같이!
package test4;
import java.util.Comparator;
import java.util.PriorityQueue;
public class test1 {
public static void main(String[] args) {
//람다 표현식
//함수를 간결하게 표현한 것
//메서드의 길이가 짧은 경우
//전통적으로 자바는 객체지향 언어
//본래는 함수가 객체를 떠나서 독자적으로 존재할 수 없었다.
//람다식은 함수형 프로그래밍을 자바에 도입한 것
//매개변수로 람다함수를 전달 가능
//문법 : (파라미터)->{본문}
//파라미터가 단일 매개변수일 때 () 생략 가능
//본문이 단일 문장일 때 {} 생략 가능
PriorityQueue<person> pq=new PriorityQueue<>((o1, o2)->{
if(o1.name.equals(o2.name)) {
return o1.age-o2.age;
}
else {
return o1.name.compareTo(o2.name);
}
});
pq.offer(new person("강현", 26));
pq.offer(new person("강현", 27));
pq.offer(new person("강현이", 28));
pq.offer(new person("강현삼", 29));
pq.offer(new person("강현사", 30));
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
System.out.println(pq.poll());
}
}
//
person [name=강현, age=26]
person [name=강현, age=27]
person [name=강현사, age=30]
person [name=강현삼, age=29]
person [name=강현이, age=28]