스택은 데이터를 저장하는 선형 자료구조로, 데이터를 쌓아 올리는 형태의 특징을 가지고 있습니다. 이를테면, 접시를 쌓는 것처럼 가장 위에 추가된 데이터가 가장 먼저 제거되어야 하는 구조입니다.이러한 특성 때문에 스택은 'Last-In,First-Out'(LIFO)라고도 불립니다.
pop(): 스택에서 가장 위에 있는 항목을 제거한다.
push(item): item 하나를 스택의 가장 윗 부분에 추가한다.
peek(): 스택의 가장 위에 있는 항목을 반환한다.
isEmpty(): 스택이 비어 있을 때에 true를 반환한다.
MyStack
package com.example.datastructure.Stack;
import com.example.datastructure.List.MyLinkedList;
public class MyStack<T> implements IStack<T>{
private int size;
private Node head;
public MyStack() {
this.size = size();
this.head = new Node(null);
}
@Override
public void push(T data) {
Node node = new Node(data, this.head.next);
this.head.next = node;
this.size++;
}
// 하나 가져오기
@Override
public T pop() {
if(this.isEmpty()){
return null;
}
Node curr = this.head.next;
this.head.next = curr.next;
curr.next = null;
this.size--;
return curr.data;
}
// 데이터 확인
@Override
public T peek() {
if(this.isEmpty()){
return null;
}
return this.head.next.data;
}
private boolean isEmpty() {
return this.head.next == null;
}
@Override
public int size() {
return this.size;
}
private class Node{
T data;
Node next;
Node(T data){
this.data = data;
}
Node(T data, Node next){
this.data = data;
this.next = next;
}
}
}
백준 9012. 괄호
package com.example.datastructure.Stack;
import java.util.Scanner;
import java.util.Stack;
public class Baekjoon_9012 {
public static void logic(String s){
Stack<Character> stack = new Stack<>();
int i = 0;
while(i < s.length()){
char c = s.charAt(i);
if(c == '('){
stack.push(c);
}else{
if(stack.size() < 1)
{
System.out.println("NO");
return;
}
stack.pop();
}
i++;
}
if(stack.size() > 0){
System.out.println("NO");
}else{
System.out.println("YES");
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
for(int i = 0; i < num; i++){
logic(sc.next());
}
}
}
스택과 마찬가지로 큐(Queue)도 데이터를 저장하는 선형 자료구조입니다. 하지만 스택과는 다르게 큐는 데이터를 '선입선출(First-In, First-Out, FIFO)' 방식으로 관리합니다. 큐는 일상 생활에서 줄을 서는 것을 생각하면 이해하기 쉽습니다. 먼저 온 사람이 먼저 나가는 것과 마찬가지로, 큐에 들어온 데이터 중 가장 먼저 들어온 데이터가 먼저 처리되는 구조입니다.
Enqueue: 큐에 데이터를 추가하는 연산입니다. 이때 데이터는 큐의 뒤쪽에 추가됩니다.
Dequeue: 큐에서 가장 앞에 있는 데이터를 제거하고 반환하는 연산입니다.
MyLinkedQueue
package com.example.datastructure.Queue;
public class MyLinkedQueue<T> implements IQueue<T>{
private Node head;
public Node tail;
private int size;
public MyLinkedQueue(){
this.size = 0;
this.head = new Node(null);
this.tail = this.head;
}
@Override
public void offer(T data) {
Node node = new Node(data);
this.tail.next = node;
this.tail = this.tail.next;
this.size++;
}
@Override
public T poll() {
if(this.isEmpty()){
throw new IllegalStateException();
}
Node node = this.head.next;
this.head.next = node.next;
node.next = null;
this.size--;
if(this.head.next == null){
this.tail = this.head;
}
return node.data;
}
// 데이터를 빼지 않고 가장 앞에 있는 데이터를 가지고 나옴
@Override
public T peek() {
if(this.isEmpty()){
throw new IllegalStateException();
}
return this.head.data;
}
@Override
public int size() {
return this.size;
}
@Override
public void clear() {
this.head.next = null;
this.tail = this.tail.next;
this.size++;
}
@Override
public boolean isEmpty() {
return this.head.next == null;
}
private class Node{
T data;
Node next;
Node(T data){
this.data = data;
}
Node(T data, Node next){
this.data = data;
this.next = next;
}
}
}
MyCircularQueue
package com.example.datastructure.Queue;
public class MyCircularQueue<T> implements IQueue<T>{
// 배열을 통해 구현
private T[] elements;
private int front;
private int rear;
private int maxSize;
public MyCircularQueue(int size){
this.elements = (T[]) new Object[size + 1];
this.front = 0;
this.rear = 0;
this.maxSize = size + 1;
}
@Override
public void offer(T data) {
if(this.isFull()){
throw new IllegalStateException();
}
this.rear = (this.rear + 1) % this.maxSize;
this.elements[this.rear] = data;
}
@Override
public T poll() {
if(this.isEmpty()){
throw new IllegalStateException();
}
this.front = (this.front + 1) % this.maxSize;
return this.elements[this.front];
}
@Override
public T peek() {
if(this.isEmpty()){
throw new IllegalStateException();
}
return this.elements[this.front + 1];
}
@Override
public int size() {
if(this.front <= this.rear){
return this.rear - this.front;
}
return this.maxSize - this.front + this.rear;
}
@Override
public void clear() {
this.front = 0;
this.rear = 0;
}
@Override
public boolean isEmpty() {
return this.front == this.rear;
}
private boolean isFull(){
return (this.rear + 1) % this.maxSize == this.front;
}
}
백준 2164번. 카드2
package com.example.datastructure.Queue;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Baekjoon_2164 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
Queue<Integer> queue = new LinkedList<>();
for(int i = 0; i < num; i++) // if 4
queue.add(i + 1); // 1, 2, 3, 4
int count = 1;
while(queue.size() != 1){
int q = queue.poll();
if(count % 2 == 0){
queue.offer(q);
}
count++;
}
System.out.println(queue.peek());
}
}