Home Stack
Post
Cancel

Stack

Stack

  • 가장 마지막으로 들어간 데이터가 가장 첫 번째로 나오는 성질(LIFO(후입선출), Last In First Out)을 가진 자료 구조이다.

image



  • [JVM 함수 호출 스택, Stack Overflow 에러] 에서의 스택



JVM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class JvmStack {

    public static void main(String[] args) {
        JvmStack jvmStack = new JvmStack();
        jvmStack.add();
    }

    public void add(){
        minus();
        mul();
    }

    public void minus(){
        System.out.println("minus");
    }
    public void mul(){
        System.out.println("mul");
    }
}

image

image

image



특징

  • 배열과 달리 index 같은 위치 값으로 접근할 수가 없다.
    검색시. 제일 상위 값부터 검색해야 하므로 O(1)~O(n) 의 시간이 걸린다.
  • 데이터 추가 및 삭제는 O(1)
    배열처럼 원소들을 하나씩 밀어줄 필요가 없다.
  • 한 쪽 끝에서만 자료를 넣고 뺄 수 있다.
  • Stack이 List도 상속받고 있어 List의 메소드도 사용가능하다.

image




기본연산

  • pop() : 스택에서 가장 위에 있는 항목을 제거한다.
  • push(item) : item 하나를 스택의 가장 윗 부분에 추가한다.
  • peek() : 스택의 가장 위에 있는 항목을 반환(조회)한다. pop 메소드와는 달리 스택에서 제거하지는 않는다.
  • isEmpty() : 스택이 비어 있을 때에 true를 반환한다.
  • clear() : 스택에 존재하는 모든 자료들을 삭제한다.



push와 pop할 때는 해당 위치를 알고 있어야 하므로 기억하고 있는 ‘스택 포인터(SP)’가 필요하다.

스택 포인터는 다음 값이 들어갈 위치를 가리키고 있다. (처음 기본값은 -1)

1
2
3
public boolean isEmpty(){
    return sp == -1;
}



push()

item 하나를 스택의 가장 윗 부분에 추가

image



pop()

스택에서 가장 위에 있는 항목을 제거

image



peek()

스택의 가장 위에 있는 항목을 반환

image



isEmpty()

스택이 비어 있을 때에 true를 반환

image



isFull()

스택이 꽉차 있을 때 true를 반환

image




코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
class Stack{
	private int sp;
	private int stackSize;
	private char stackArr[];

	// 스택이 비어있는 상태인지 확인
	// 스택 포인터가 -1인 경우 데이터가 없는 상태이므로 true 아닌 경우 false를 return
	public boolean isEmpty(){
		return sp == -1;
	}

	// 스택이 가득찬 상태인지 확인
	// 스택 포인터가 스택의 마지막 인덱스와 동일한 경우 true 아닌 경우 false를 return
	public boolean isFull(){
		return sp == this.stackSize -1;
	}

	// 스택에 데이터를 추가
	public void push (char item){
		if(isFull()){
			System.out.println("Stack is full!");
		}
		else{
			stackArr[++sp] = item; // sp 값이 먼저 증가된 후에 해당 코드 실행
			System.out.println("입력된 문자 : " + item);
		}
	}

	// 스택의 최상위(마지막) 데이터 추출 후 삭제
	public char pop(){
		if (isEmpty()) {
			System.out.println("Deleting fail! Stack is empty!");
			return 0;
		} else {
			System.out.println("삭제된 문자 : " + stackArr[sp]);
			return stackArr[sp--]; // 해당 코드가 실행 된 후 sp 값 감소
		}
	}

	// 스택의 최상위(마지막) 데이터 추출
	public char peek(){
		if (isEmpty()){
			System.out.println("Peeking fail! Stack is empty!");
			return 0;
		}
		else {
			System.out.println("최상위 문자 조회 : " + stackArr[sp]);
			return stackArr[sp];
		}
	}

	// 스택 초기화
	public void clear(){
		if (isEmpty()){
			System.out.println("Stack is already empty!");
		} else {
			sp = -1; // 스택 포인터 초기화
			stackArr = new char[this.stackSize]; // 새로운 스택 배열 생성
			System.out.println("Stack is clear!");
		}
	}

	// 스택을 생성하는 생성자
	public Stack(int stackSize){
		sp = -1; // 스택 포인터 초기화
		this.stackSize = stackSize; // 스택 사이즈 설정
		stackArr = new char[this.stackSize]; // 스택 배열 생성
	}

	// 스택에 저장된 모든 데이터를 출력
	public void printStack(){
		if (isEmpty()) {
			System.out.println("Stack is empty!");
		} else {
			System.out.print("Stack elements : ");
			for (int i =0; i<=sp; i++) {
				System.out.print(stackArr[i] + " ");
			}
			System.out.println();
		}
	}

}

public class StackTest {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in); // 사용자로부터 키 입력을 받기 위해서는 System.in을 사용한다.
		System.out.print("스택 사이즈를 입력하세요. :  ");
		int stackSize = scanner.nextInt(); // int nextInt() : 입력받은 값을 int 타입으로 반환

		Stack stack = new Stack(stackSize);

		stack.push('A');
		stack.printStack();

		stack.push('B');
		stack.printStack();

		stack.push('C');
		stack.printStack();

		stack.pop();
		stack.printStack();

		stack.peek();
		stack.printStack();

		stack.clear();
		stack.printStack();
	}
}

// https://velog.io/@kungsboy/%EC%88%99%EC%A0%9C-Stack-%EA%B5%AC%ED%98%84

image




동작 배열 스택

스택에는 MAX_SIZE라는 최대 크기가 존재해야 한다.

→ 스택 포인터와 MAX_SIZE를 비교해서 isFull 메소드로 비교해야되기 때문이다.


최대 크기가 없는 스택을 만드려면?

arraycopy를 활용한 동적배열 사용한다.(스택이 최대가 되면 스택 크기를 2배로 늘리는 방법이다.)

image




활용

  • 재귀 알고리즘
    • 재귀적으로 함수를 호출해야하는 경우 임시 데이터를 스택에 넣어준다.
    • 재귀함수를 빠져 나와 퇴각 검색(backtrack)을 할 때는 스택에 넣어 두었던 임시 데이터를 빼 줘야 한다.
    • 스택은 이런 일련의 행위를 직관적으로 가능하게 해 준다.
    • 또한 스택은 재귀 알고리즘을 반복적 형태(iterative)를 통해서 구현할 수 있게 해준다.
  • 웹 브라우저 방문기록(뒤로가기)
  • 실행 취소
  • 역순 문자열 만들기
  • 수식의 괄호 검사
  • 후위 표기법 계산
This post is licensed under CC BY 4.0 by the author.