한 쪽 끝에서만 자료를 넣고 뺄 수 있는 LIFO 형식의 자료구조
push | pop | Peek | Search |
---|---|---|---|
O(1) | O(1) | O(1) | O(n) |
import java.util.Stack; public class Test { public static void main(String[] args) { Stack<Integer> stack = new Stack<>(); stack.push(1); stack.push(2); stack.push(3); System.out.println(stack.get(1)); // 해당 인덱스 원소 찾기 System.out.println(stack.set(1, 1)); // 해당 인덱스에 원소 넣기 System.out.println(stack.remove(1)); // 해당 인덱스 원소를 삭제 } }
ArrayDeque 공식문서를 보면 스택구조로 사용하면 Stack 클래스보다 빠르고
, 큐 구조로 사용하면 Queue 클래스보다 빠르다
고 되어 있다.(ArrayDeque는 Thread-Safe하지 않기 때문입니다.)
따라서 LIFO 구조를 만들기 위해 적합한 클래스는 Deque 인터페이스를 구현하는 ArrayDeque클래스이다.
package algorithmStudyStack;
import Interface_form.StackInterface;
import java.util.Arrays;
import java.util.EmptyStackException;
public class Stack<E> implements StackInterface<E> {
private static final int DEFAULT_CAPACITY = 10; //최소(기본) 용량 크기
private static final Object[] EMPTY_ARRAY = {}; //빈 배열
private Object[] array; //요소를 담을 배열
private int size; //요소 개수
//생성자
public Stack(){
this.array = EMPTY_ARRAY;
this.size = 0;
}
public Stack(int capacity){
this.array = new Object[capacity];
this.size = 0;
}
//동적할당을 위한 resize 메소드
private void resize() {
//빈 배열일 경우(capacity is 0)
if (Arrays.equals(array, EMPTY_ARRAY)) {
array = new Object[DEFAULT_CAPACITY];
return;
}
int arrayCapacity = array.length; //현재 용량 크기
//용량이 가득 창 경우
if (size == arrayCapacity) {
int newSize = arrayCapacity * 2;
//배열 복사
array = Arrays.copyOf(array, newSize);
return;
}
//용량의 절반 미만으로 요소가 차지하고 있을 경우
if(size <(arrayCapacity/2)){
int newCapacity = (arrayCapacity/2);
//배열 복사
array = Arrays.copyOf(array,Math.max(DEFAULT_CAPACITY,newCapacity));
return;
}
}
@Override
public E push(E item){
//용량이 꽉 차있다면 용량을 재할당
if(size ==array.length){
resize();
}
array[size] = item; //마지막 위치에 요소 추가
size++;
return item;
}
@Override
public E pop(){
//만약 삭제할 요소가 없다면 Stack이 비어있다는 의미이므로 예외처리
if(size ==0){
throw new EmptyStackException();
}
@SuppressWarnings("unchecked")
E obj = (E) array[size-1];//삭제될 요소를 반환하기 위한 임시 변수
array[size-1] = null; //요소 삭제
size--;
resize();
return obj;
}
@SuppressWarnings("unchecked")
@Override
public E peek(){
if(size==0){
throw new EmptyStackException();
}
return (E) array[size-1];
}
@Override
public int search(Object value){
for(int idx = size-1;idx>=0;idx--){
//같은 객체를 찾았을 경우 size-idx값을 반환
if(array[idx].equals(value)){
return size-idx;
}
}
return -1;
}
@Override
public int size(){
return size;
}
@Override
public void clear(){
for(int i=0;i<size;i++){
array[i] = null;
}
size = 0;
resize();
}
@Override
public boolean empty(){
return size ==0;
}
}