[Data Structures | C++] Stack : 스택

스택(Stack) #

  • 스택은 마지막에 저장한 데이터를 가장 먼저 꺼내는 후입선출(LIFO:Last In First Out) 구조로 되어 있다.
  • 입출력이 모두 한 방향에서 이루어지는 데이터 구조이다.
  • 입출력이 가능한 쪽을 TOP, 바닥을 BOTTOM이라고 한다.
  • TOP은 출력 우선순위가 가장 높은 요소를 가리키고 있다.
  • 입출력을 할 위치를 표시하기 위해서 TOP(포인터 사용)이 필요하다.
  • TOP을 통해서 데이터를 넣는 것을 PUSH라고 하고, 꺼내는 것을 POP이라고 한다.
  • 스택을 구현하는 방법은 배열과 연결 리스트가 있다.
  • 배열의 큰 단점은 처음 생성한 크기를 바꿀 수 없다는 점이다. 그래서 순차적으로 데이터를 추가하고 삭제하는 스택은 배열리스트(Array List)와 같은 배열기반의 컬렉션 클래스가 적합하다.
  • overflow : 스택의 모든 기억장소가 꽉 채워져 있어서 더 이상 데이터를 삽입(PUSH할 때)할 수 없다.
  • underflow : 자료가 없다면(TOP포인터가 주소 0을 가지고 있다면) 스택에는 삭제(POP할 때)할 자료가 없다.

스택(Stack)의 연산 #

스택(Stack)는 LIFO(Last In First Out) 를 따른다. 즉, 가장 최근에 스택에 추가한 항목이 가장 먼저 제거될 항목이다.

  • pop() : 스택에서 가장 위에 있는 항목을 제거한다.
  • push(item) : item 하나를 스택의 가장 윗 부분에 추가한다.
  • peek() : 스택의 가장 위에 있는 항목을 반환한다.
  • isEmpty() : 스택이 비어 있을 때에 true를 반환한다.

스택의 단점 #

  • 먼저 들어온 것이 나중에 출력되는 후입선출의 구조로 우선순위에 관련된 문제가 생길 수 있다.
  • 새로운 입력이 들어오면 바닥에 있는 데이터가 오랫동안 잔류하게 되는 경우가 생긴다.

스택의 용도 #

재귀 알고리즘을 사용하는 경우 스택이 유용하다.

  • 재귀 알고리즘
    • 재귀적으로 함수를 호출해야 하는 경우에 임시 데이터를 스택에 넣어준다.
    • 재귀함수를 빠져 나와 퇴각 검색(backtrack)을 할 때는 스택에 넣어 두었던 임시 데이터를 빼 줘야 한다.
    • 스택은 이런 일련의 행위를 직관적으로 가능하게 해 준다.
    • 또한 스택은 재귀 알고리즘을 반복적 형태(iterative)를 통해서 구현할 수 있게 해준다.
  • 웹 브라우저 방문기록 (뒤로가기)
  • 실행 취소 (undo)
  • 역순 문자열 만들기
  • 수식의 괄호 검사 (연산자 우선순위 표현을 위한 괄호 검사)
    • Ex) 올바른 괄호 문자열(VPS, Valid Parenthesis String) 판단하기
  • 후위 표기법 계산
  • 지역변수 저장
  • 함수의 콜스택
  • 문자열을 역순으로 출력할 때, 연산자 후위표기법 등
  • 임시데이터 백업
  • 함수 호출의 순서 제어
  • 인터럽트 처리
  • 수식계산

C++로 구현한 스택 (Stack) #

 1class Stack
 2{
 3private:
 4	DoubleList *doublelist;
 5public:
 6	Stack();
 7	~Stack();
 8
 9	DoubleList *getdouble() { return doublelist; }
10
11	void Push(int data, int position);
12	void Pop(int position);
13	void display();
14};
15
16#include "Stack.h"
17
18Stack::Stack()
19{
20	doublelist = new DoubleList;
21}
22
23Stack::~Stack()
24{
25}
26
27void Stack::Push(int data, int position) {
28	doublelist->insertNode(data, position);
29}
30
31void Stack::Pop(int position) {
32	doublelist->delNode(position);
33}
34
35void Stack::display() {
36	doublelist->displayNode();
37}
38
39//Manager.cpp
40void Manager::StackRun() {
41	int menu = 0;
42	int _data = 0;
43
44	while (true)
45	{
46		cout << "1.삽입\n2.반환\n3.출력\n입력 : ";
47		cin >> menu;
48
49		switch (menu)
50		{
51		case INSERT:
52			cout << "추가 할 데이터 : ";
53			cin >> _data;
54			stack->Push(_data, 0);
55			stack->display();
56			break;
57		case DEL:
58			stack->Pop(0);
59			stack->display();
60			break;
61		case COUT:
62			if (stack->getdouble()->getHead() == NULL) {
63				cout << "데이터가 없습니다." << endl << endl;
64			}
65			else {
66				stack->display();
67			}
68			break;
69		default:
70			break;
71		}
72	}
73}
Advertisement