-
728x90
본 포스팅은 jisikTank 스터디에 참여하며 정리한 문서입니다.
jisikTank CS지식 Git Repository
스택과 큐(Stack & Queue)
스택(Stack)
- 입력과 출력이 한 곳(방향)으로 제한
- LIFO(Last In First Out, 후입선출): 가장 나중에 들어온 것이 가장 먼저 나옴
언제 사용할까?
- 함수의 콜스택, 문자열 역순 출력, 연산자 후위표기법 등
Stack의 특징
- 자주 사용하는 메소드로 push, pop, isEmpty, isFull 이 있다.
- push, pop 과정에 다음 값이 들어갈 최상단 위치를 기억하는
스택 포인터(SP)
가 필요(처음 기본값 -1) - 기본적으로 크기가 정적으로 구성되지만
연결리스트, 동적 배열
을 활용해최대 크기가 존재하지 않도록 구현
할 수 있다. - 시간복잡도 삽입 O(1), 삭제 O(1), 탐색 O(n)
public class BasicStack {static int MAX_SIZE = 1000;static Object stack[];class Stack{private int sp = -1;public void push(Object o) {if(isFull(o)) {return;}stack[++sp] = o;}public void pushDynamicArrayStack(Object o) {if(isFull(sp)) {Object[] arr = new Object[MAX_SIZE * 2];System.arraycopy(stack, 0, arr, 0, MAX_SIZE);stack = arr;MAX_SIZE *= 2; // 2배로 증가}stack[sp++] = o;}public Object pop() {if(isEmpty(sp)) {return null;}Object o = stack[sp--];return o;}private boolean isFull(Object o) {return sp + 1 == MAX_SIZE ? true : false;}private boolean isEmpty(int cnt) {return sp == -1 ? true : false;}}public static void main(String args[]){}}
동적 크기 스택(Array형태로 구현)public class DynamicArrayStack {static int MAX_SIZE = 1000;static Object stack[];class Stack{private int sp = -1;// 일반 스택과 push method만 차이가 있음public void push(Object o) {if(isFull(sp)) {Object[] arr = new Object[MAX_SIZE * 2];System.arraycopy(stack, 0, arr, 0, MAX_SIZE);stack = arr;MAX_SIZE *= 2; // 2배로 증가}stack[sp++] = o;}public Object pop() {if(isEmpty(sp)) {return null;}Object o = stack[sp--];return o;}private boolean isFull(Object o) {return sp + 1 == MAX_SIZE ? true : false;}private boolean isEmpty(int cnt) {return sp == -1 ? true : false;}}}
동적 크기 스택(LinkedList로 구현)public class DynamicLinkedListStack {public class Node {public int data;public Node next;public Node() {}public Node(int data) {this.data = data;this.next = null;}}public class Stack {private Node head;private Node top;public Stack() {head = top = null;}private Node createNode(int data) {return new Node(data);}private boolean isEmpty() {return top == null ? true : false;}public void push(int data) {if (isEmpty()) { // 스택이 비어있다면head = createNode(data);top = head;}else { //스택이 비어있지 않다면 마지막 위치를 찾아 새 노드를 연결시킨다.Node pointer = head;while (pointer.next != null)pointer = pointer.next;pointer.next = createNode(data);top = pointer.next;}}public int pop() {int popData;if (!isEmpty()) { // 스택이 비어있지 않다면!! => 데이터가 있다면!!popData = top.data; // pop될 데이터를 미리 받아놓는다.Node pointer = head; // 현재 위치를 확인할 임시 노드 포인터if (head == top) // 데이터가 하나라면head = top = null;else { // 데이터가 2개 이상이라면while (pointer.next != top) // top을 가리키는 노드를 찾는다.pointer = pointer.next;pointer.next = null; // 마지막 노드의 연결을 끊는다.top = pointer; // top을 이동시킨다.}return popData;}return -1; // -1은 데이터가 없다는 의미로 지정해둠.}}public static void main(String[] args) {}}
큐(Queue)
- 입력과 출력을 한 쪽 끝(front, rear)로 제한
- FIFO(First In First Out, 선입선출): 가장 먼저 들어온 것이 가장 먼저 나옴
언제 사용할까?
- 버퍼, 마구 입력된 것을 처리하지 못하고 있는 상황, BFS
Queue의 특징
큐의 가장 첫 원소를 front, 끝 원소를 rear라고 부름
접근은 가장 첫 원소와 끝 원소로만 가능
자주 사용하는 메소드로 enQueue, deQueue, isEmpty, isFull이 있음
시간복잡도 삽입 O(1), 삭제 O(1), 탐색 O(n)
일반 큐(선형)는 빈 메모리가 남아 있어도, 꽉 차있는 것으로 판단할 수 있음(rear가 끝에 도달했을 때) ->
원형 큐
원형 큐
- 논리적으로 배열의 처음과 끝이 연결되어 있는 것으로 간주함
- 초기 공백 상태일 때 front와 rear가 0
- 공백, 포화 상태를 쉽게 구분하기 위해 자리 하나를 항상 비워둠
(index + 1) % size로 순환시킨다
java 코드로 큐 알아보기
일반 정적 크기 큐 코드public class BasicQueue {class Queue{private int size = 0;private int rear = -1;private int front = -1;private Object queue[];Queue(int size) {this.size = size;this.queue = new Object[size];}public boolean isEmpty() {return front == rear;}public boolean isFull() {return (rear == size-1);}public void enQueue(Object o) {if(isFull()) {return;}queue[++rear] = o;}public Object deQueue() {if(isEmpty()) {return null;}Object o = queue[front];queue[front++] = null;return o;}}}
java 원형 큐 코드
public class Circular {public class Circular_Queue {int rear = 0; //최초 0에서부터 시작int front = 0; //최초 0에서부터 시작int maxsize = 0; //배열의 크기int[] circular_Queue; //배열public Circular_Queue(int maxsize){this.maxsize = maxsize;circular_Queue = new int[this.maxsize];}public boolean Isempty() //배열이 공백 상태인지 체크하는 메서드입니다.{if(rear == front){return true;}return false;}public boolean Isfull() //배열이 포화 상태인지 체크하는 메서드입니다.{if((rear+1)%maxsize == front){return true;}return false;}public void EnQueue(int num){if(Isfull()) //배열이 포화상태일경우{System.out.println("큐가 가득 찼습니다");}else //배열이 포화상태가 아닐경우{rear = (rear+1) % maxsize;circular_Queue[rear]=num;}}public int DeQueue(){if(Isempty()) //배열이 공백상태이면 -1반환{return -1;}else //배열이 공백상태가 아니라면{front = (front+1)%maxsize;return circular_Queue[front];}}}public static void main(String[] args) {}}Quiz
- 기본적인 스택과 큐를 구현해보세요.
- Stack과 Queue의 차이점은 무엇인가요?(N사 전화면접)
https://devowen.com/285
참고 자료
Quiz 모범 답안
'CS > Data Structure' 카테고리의 다른 글
Hash 자료구조 알아보기 (0) 2021.04.20 이진탐색트리(Binary Search Tree) 자료구조 (0) 2021.04.20 PriorityQueue와 Heap 자료구조 (0) 2021.04.20 트리 자료구조의 개념과 이진 트리 순회 (0) 2021.04.17 Array, LinkedList, ArrayList 비교 (0) 2021.04.17