반응형
스택(Stack)
- 먼저 들어간 것이 나중에 나오는 자료구조
- LIFO(Last-in, First-out) 구조
스택 자료구조의 추상 자료형(ADT)
boolean SIsEmpty(); //스택이 비어있는지 확인하는 메소드
void SPush(T data); //스택에 데이터를 저장하는 메소드
T SPop(); //스택의 마지막에 저장된 요소를 삭제하는 메소드
T SPeek(); //스택의 마지막에 저장된 요소를 조회하는 메소드
배열기반 스택
public class ArrayStack<T> {
private static final int DEFAULT_ARRAY_SIZE = 8;
private T[] stackArr;
private int top;
public ArrayStack(Class<T> type) {
stackArr = (T[]) Array.newInstance(type, DEFAULT_ARRAY_SIZE);
top = -1;
}
/**
* 스택이 비었는지 확인
* @return
*/
public boolean SIsEmpty() {
if(top == -1)
return true;
return false;
}
/**
* 스택의 push 연산
* @param data
*/
public void SPush(T data) {
top++;
this.stackArr[top] = data;
}
/**
* 스택의 pop 연산
* @return
*/
public T SPop() {
//Spop() 내부에서는 해당 위치가 유효한 데이터의 위치임을 보장한다.
//배열에서의 삭제는 해당 위치의 값을 초기화 시켜주지 않아도 된다.
//top의 위치가 변경되면 기존 위치에 데이터가 있더라도 유효한 데이터로 인정되지 못한다.
if(SIsEmpty()) {
new ArrayIndexOutOfBoundsException("Stack Memory Error!");
}
int rIdx = top;
top--;
return this.stackArr[rIdx];
}
/**
* 스택의 peek 연산
* @return
*/
public T SPeek() {
if(SIsEmpty()) {
System.out.println("Stack Memory Error!");
}
return this.stackArr[top];
}
public static void main(String[] args) {
// Stack의 생성 및 초기화 ///////
ArrayStack<Integer> stack = new ArrayStack<>(Integer.class);
// 데이터 넣기 ///////
stack.SPush(1);
stack.SPush(2);
stack.SPush(3);
stack.SPush(4);
stack.SPush(5);
// 데이터 꺼내기 ///////
while(!stack.SIsEmpty())
System.out.printf("%d ", stack.SPop());
}
}
배열기반 스택의 단점
- 배열의 특징을 가진다.
- 중간 삽입, 삭제 과정이 없으므로 불필요한 데이터의 이동이 발생하지 않으나 초기에 저장공간을 할당받아야 한다.
저장공간을 모두 활용하지 않는다면 저장공간이 낭비될 수 있다.
배열기반 스택의 장점
- 배열의 특징을 가진다.
- 연결리스트기반 스택에 비해 데이터 저장 공간을 효율적으로 사용한다.
연결리스트기반 스택
public class LinkedListStack<T> {
//노드를 표현한 클래스
private class Node{
private T data;
private Node nextLink;
private Node() {
this.data = null;
this.nextLink = null;
}
private Node(T data) {
this.data = data;
this.nextLink = null;
}
}
private Node head;
public LinkedListStack() {
head = null;
}
/**
* 스택이 비었는지 확인
* @return
*/
public boolean SIsEmpty() {
if(head == null)
return true;
return false;
}
/**
* 스택의 push 연산
* @param data
*/
public void SPush(T data) {
Node newNode = new Node(data);
newNode.nextLink = head;
head = newNode;
}
/**
* 스택의 pop 연산
* @return
*/
public T SPop() {
if(SIsEmpty())
new ArrayIndexOutOfBoundsException("Stack Memory Error!");
T rdata = head.data;
head = head.nextLink;
return rdata;
}
/**
* 스택의 peek 연산
* @return
*/
public T SPeek() {
if(SIsEmpty())
new ArrayIndexOutOfBoundsException("Stack Memory Error!");
return head.data;
}
public static void main(String[] args) {
// Stack의 생성 및 초기화 ///////
LinkedListStack<Integer> stack = new LinkedListStack<>();
// 데이터 넣기 ///////
stack.SPush(1);
stack.SPush(2);
stack.SPush(3);
stack.SPush(4);
stack.SPush(5);
// 데이터 조회 ///////
System.out.println(stack.SPeek());
// 데이터 꺼내기 ///////
while(!stack.SIsEmpty())
System.out.printf("%d ", stack.SPop());
}
}
연결리스트기반 스택의 단점
- 연결리스트의 특징을 가진다.
- 배열기반 스택에 비해 데이터 저장 시 활용하는 메모리가 더 크다. (데이터 + 연결리스트 주소)
연결리스트기반 스택의 장점
- 연결리스트의 특징을 가진다.
- 초기에 저장 공간을 할당받는 배열기반 스택과 달리 연결리스트기반 스택은 저장 공간의 제약이 없다.
[참고자료]
윤성우의 열혈 자료구조
반응형
'Data Structure > 기본' 카테고리의 다른 글
[윤성우의 열혈 자료구조]덱(Double ended queue, Deque) - 자바(Java) 구현 (0) | 2021.06.12 |
---|---|
[윤성우의 열혈 자료구조]큐(Queue) - 자바(Java) 구현 (0) | 2021.06.10 |
[윤성우의 열혈 자료구조]양방향 연결리스트(Doubly linked list) - 자바(Java) 구현 (0) | 2021.06.08 |
[윤성우의 열혈 자료구조]원형 연결리스트(Circular linked list) - 자바(Java) 구현 (0) | 2021.06.05 |
[윤성우의 열혈 자료구조]단순 연결리스트(Singly linked list) - 자바(Java) 구현 (0) | 2021.06.04 |