본문 바로가기
알고리즘/JAVA_알고리즘 클래스, 함수 정리

[자료구조 기초] Stack, Queue, PriorityQueue, Deque

by Develaniper 2021. 4. 6.
  Stack Queue Deque PriorityQueue
구조 LIFO(LastInFirstOut) FIFO(FirstInFirstOut) FIFO(FirstInFirstOut) FIFO(FirstInFirstOut)
활용 DFS BFS 최소/최대 값의 삽입, 삭제 작업이 잦을 때 -
입력 push(obj) add(obj) / offer(obj)
앞쪽에 - 뒤쪽에
addFirst(obj) - addLast(obj)
add(obj) / offer(obj)
출력 peek(); element() / peek() 앞쪽에서 - 뒤쪽에서

peekFirst() - peekLast();


element() / poll()
출력 & 제거 pop(); remove() / poll()  앞쪽에서 - 뒤쪽에서
removeFirst() - removeLast()
/
pollFirst() - 
pollLast()
remove() / peak()
원소 없을 때 Exception 발생 null 반환 / Exception 발생 null 반환 / Exception 발생 null 반환 / Exception 발생
         

 


1. Stack

 1) 기본 사용법

import java.util.*;
public class Exam {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.push(5);
        
        while(!stack.isEmpty()){
            System.out.print(stack.pop()+ " ");
        }
    }
}
// 출력
// 5 4 3 2 1 

마지막에 push한 것이 가장 먼저 출력 되는 것을 볼 수 있다.

 

 

2. Queue

  1) 기본 사용법

import java.util.*;
public class Exam {
    public static void main(String[] args) {
        Queue<Integer> q = new LinkedList<>();
        q.add(1);
        q.add(2);
        q.add(3);
        q.add(4);
        q.add(5);
        q.add(6);
        
        while(!q.isEmpty()){
            System.out.print(q.poll()+" ");
        }
    }
}
// 출력
// 1 2 3 4 5 6 

가장 먼저 add(enqueue) 한것이 가장 먼저 출력되는 것을 볼 수 있다.

 

 

3. Deque

  1) 기본 사용법

import java.util.*;
public class Exam {
    public static void main(String[] args) {
        Deque<Integer> dq = new ArrayDeque<>();
        dq.addFirst(1);
        dq.addFirst(2);
        dq.addFirst(3);
        dq.addFirst(4);
        dq.addLast(5);
        dq.addLast(6);
        dq.addLast(7);
        for (Integer d : dq) {
            System.out.print(d+ " ");
        }
        System.out.println();

        dq.pollFirst();		// poll을 이용해 앞쪽에서 제거
        for (Integer d : dq) {
            System.out.print(d+ " ");
        }
        System.out.println();

        dq.pollLast();		// poll을 이용해 뒤쪽에서 제거
        for (Integer d : dq) {
            System.out.print(d+ " ");
        }
        System.out.println();

        dq.removeFirst();		// remove를 이용해 앞쪽에서 제거
        for (Integer d : dq) {
            System.out.print(d+ " ");
        }
        System.out.println();

        dq.removeLast();		// remove를 이용해 뒤쪽에서 제거
        for (Integer d : dq) {
            System.out.print(d+ " ");
        }
    }
}
// 4 3 2 1 5 6 7 
// 3 2 1 5 6 7
// 3 2 1 5 6
// 3 2 1 5
// 3 2 1

 1을 기준으로 보면 addFirst를 통해 Deque에 넣으면 앞쪽으로 addLast를 통해 Deque에 넣으면 뒷쪽으로 입력되는 것을 볼 수 있다.

 Deque에서 객체를 빼낼 때도 마찬가지로 remove, poll을 이용하여 앞쪽과 뒷쪽 중에 원하는 쪽에서 원소를 뺄 수 있다.

 

4. PriorityQueue

  1) 기본 사용법

import java.util.*;
public class Exam {
    public static void main(String[] args) {
    	// 최소힙(기본값)
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        // 최대힙(Collections.reverseOrder()로 지정)
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());


        minHeap.add(4);
        minHeap.add(5);
        minHeap.add(1);
        minHeap.add(6);
        minHeap.add(8);

        maxHeap.add(4);
        maxHeap.add(5);
        maxHeap.add(1);
        maxHeap.add(6);
        maxHeap.add(8);


        for (Integer integer : minHeap) {
            System.out.print( integer+ " ");   
        }
        System.out.println();
        for (Integer integer : maxHeap) {
            System.out.print( integer+ " ");   
        }
        System.out.println();
        System.out.println();

        while(!minHeap.isEmpty()){
            System.out.print(minHeap.poll()+ " ");
        }
        System.out.println();
        while(!maxHeap.isEmpty()){
            System.out.print(maxHeap.poll()+ " ");
        }
    }
}
// 1 5 4 6 8 
// 8 6 1 4 5

// 1 4 5 6 8
// 8 6 5 4 1

 처음 원소들을 foreach문을 통해 단순 출력 했을 때는 Heap구조에 따라 원소들이 나열 된 것을 볼 수 있다.

 

두번째 poll을 통해 원소를 출력&제거를 할 때는 최소힙인 minHeap은 최소값 부터 최대힙인 maxHeap은 최대값부터 출력하는 것을 볼 수 있다.

 

  2) 커스텀

   가끔 단순한 minHeap, maxHeap과 같이 오른차순, 내림차순으로 우선순위를 정할 수 없을 때가 있다. 이때 Comparater를 활용하여 우선순위를 직접 설정해 주면 된다.

import java.util.*;
public class Exam {
    public static void main(String[] args) {
        PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>(){
            @Override
            public int compare(Integer a, Integer b) {
                int compareA = a>0?a:-a;
                int compareB = b>0?b:-b;
                if(compareA==compareB) return 0;
                return compareA<compareB ? -1:1;
                // -1,0 => 자리를 바꾼다 => a가 앞에 앞에 온다.
                //  1 => 자리를 바꾸지 않는다 => b가 앞에 온다.
            }
        });

        pq.add(1);
        pq.add(3);
        pq.add(7);
        pq.add(-4);
        pq.add(-5);
        pq.add(-6);


        Object obj=null;
        while((obj=pq.poll())!=null){
            System.out.print(obj+" ");
        }
    }
}
// 출력
// 1 3 -4 -5 -6 7 

위의 예제는 절대값이 작은 대로 정렬한 것을 바탕으로 priorityqueue를 작성한 것이다. Comparator를 이용하여 익명클래스를 만들어 compare를 오버라이드 하여 비교하면 간편하게 비교 할 수 있다.

※ 클래스를 만들어서 Comparable을 implements하여 compareTo를 오버라이드 해도 비교할 수 있지만 위의 방법이 더 간단한 것 같다.

댓글