[Data Structure] Stack(스택)
Abstract Data Types (추상 자료형)
추상 자료형 (ADTs)는 한마디로 말하면 알고리즘의 요약본이다. ADT는 correctness와 performance를 독립적으로 생각하게 해줄 수 있다.
Correctness는 일반적으로 interface라고도 하는데, input이 들어왔을 때, output의 일치 정확도가 얼마나 높은 가를 말한다.
Performance는 implementation이라고 하며 time complexity와 같은 것을 말한다.
ADT를 짤 때는 해당 알고리즘의 기능만을 고려하며 성능과 자세한 구현을 고려하지 않는다.
Stack (스택)
스택 개념
스택의 삽입과 삭제 원리는 Last-In First-Out(LIFO, 후입선출)로 작동한다. 말 그대로 가장 나중에 들어온 데이터가 가장 먼저 나가게 되는 구조이다.
스택이 활용되는 예시는 아래와 같은 것들이 있다.
- 웹페이지 방문기록 (뒤로가기) : 가장 최근의 방문한 페이지를 우선으로 보여준다.
- 텍스트 편집 프로그램의 되돌리기 (ctrl+z)기능
- C++프로그램에서 코드가 구동되는 시스템 : function call stack이라고 한다.
Stack ADT
스택의 추상 자료형은 다음과 같다.
- push(object) : object를 삽입한다.
- object pop() : object중 가장 마지막에 삽입된 것을 제거한다.
- object top() : 가장 마지막에 있는 object를 return해준다.
- integer size() : 저장된 object의 개수를 return해준다.
- boolean empty() : 스택이 비어있는 지 아닌 지를 반환해준다.
위의 ADT를 고려해서 stack interface를 구현해보자.
template <typename E> class Stack { public: int size() const; bool empty() const; const E& top() const throw(StackEmpty); void push(const E& e); void pop() throw(StackEmpty); };
Stack implementation (스택 구현)
스택을 구현하는 방식에는 2가지 방식이 있다.
- Array-based stack
- Linked List-based stack
Array-based Stack (배열 기반 스택)
ArrayStack prototype
#include <iostream> using namespace std; class arrayStack { public: int* S; int capacity; int t; arrayStack(int capacity); arrayStack(); int size(); bool empty(); int top(); void push(int e); int pop(); };
배열 기반 스택의 프로토타입 함수 종류들이다. 멤버변수에서 포인터 변수인 S는 실제로 저장 역할을 하는 배열이 될 것이다. 배열 기반 스택은 배열의 인덱스를 바꿔주면서 삽입, 삭제, 출력 연산을 진행하는데, 여기서 어떤 값이 가장 최근 인덱스인지를 알려주는 역할을 t변수가 할 것이다. top의 index역할이라고 생각하면 된다.
자세한 설명은 각 함수 구현과 함께 설명하겠다.
arrayStack initializer (생성자)
arrayStack(int capacity) { this->capacity = capacity; this->S = new int[capacity]; this->t = -1; }
스택의 생성자이다. 구현하려는 스택의 크기를 정해주면 그 크기에 맞춰서 스택이 형성된다.
아무런 데이터가 없는 경우에는 top의 index를 -1로 지정해준다.
push function
void push(int e) { if (t == capacity - 1) { cout << "stack is full\n"; return; } t++; S[t] = e; }
push 함수는 구현이 어려운 편이 아니다. 하지만 후에 구현할 링크드 리스트와 다르게 배열구현 스택은 크기가 정해져 있으므로 스택이 꽉 찼을 때의 예외처리를 해 줄 필요가 있다.
- 스택이 찼는 지를 확인해준다. 만약 꽉 찼다면 경고해주고 함수를 종료한다.
- 스택이 차지 않았다면 top index인 t를 증가시켜준다.
- 증가된 배열의 t index 위치에 값 e를 넣어준다.
스택이 꽉 찼는 지를 확인하는 방법은 어렵지 않다. top index가 배열의 크기보다 1개 작으면 되는 것이다. (왜 1개 작냐 생각이 든다면... 기초부터 다시 공부하는 것이 좋을거다.)
empty function
bool empty() { return t == -1; }
스택이 비었는 지를 확인하는 방법은 쉽다. 앞에서 언급했지만 top의 시작 index값은 -1이다. 즉 t가 -1이라는 것은 스택이 비어있다는 뜻과 같다.
pop function
int pop() { if(empty()) { return -1; } int tmp = S[t]; t--; return tmp; }
제거연산을 할 때는 반드시 공백여부를 확인해 줘야한다.
- 만약 스택이 비어있다면 -1을 반환해준다.
- 비어있지 않다면 우선 기존의 top 값을 저장해준다.
- top index를 1내려준다.
- 기존의 top값을 반환해준다.
size and top function
int size() { return capacity; } int top() { if (empty()) return -1; else return S[t]; }
두 함수 모두 간단한 구현이다. 그냥 필요한 값을 반환만 해주면 되기 때문다.
Linked list-based Stack
LinkedStack prototype
#include <iostream> using namespace std; class linkedStack { public: int n; SLinkedList* S; linkedStack(); int size(); bool empty(); int top(); void push(int e); int pop(); };
linked list와 node에 대한 클래스는 이전 글을 확인하거나 tistory블로그에서 확인할 수 있다. 그 두개 코드가 같이 들어가면 너무 길어진다...
여기서 n은 전체 스택의 원소개수가 된다.
linkedStack initializer (생성자)
linkedStack() { this->S = new SLinkedList; this->n = 0; }
생성자는 간단하게 초기화만 해준다.
empty function
bool empty() { return n == 0; }
큰 원리는 배열기반과 비슷하다. n이 원소의 개수를 반환해주므로 n이 0개라면 스택이 비어있다는 의미가 되게 된다.
push function
void push(int e) { S->addFront(e); n++; }
push 함수는 링크드 리스트 구현에서 사용한 addFront함수를 활용하면 된다. 스택은 최근에 들어온 값들만 확인하면 되기때문에 Front관련 함수들만 구현해서 활용하면된다.
- 링크드 리스트 S에 원소 e를 넣어준다.
- n 개수를 1 증가시켜준다.
pop function
int pop() { if (empty()) { return -1; }else { n--; return S->removeFront(); } }
스택의 공백 여부만 확인을 잘 해주면된다.
- 우선 전체 원소수를 대표하는 n을 줄여준다.
- 그 후 S의 removeFront값을 반환해준다.
size and top function
int size() { return n; } int top() { if (empty()) return -1; else return S->front(); }
같은 원리로 동작해주면 된다.
'Computer Science > 자료구조' 카테고리의 다른 글
[Data Structure] Tree (트리) (0) | 2021.06.24 |
---|---|
[Data Structure] Vector and List (벡터와 리스트) (0) | 2021.03.03 |
[Data Structure] Queue(큐) (0) | 2021.03.03 |
[Data Structure] Analysis of Algorithms (알고리즘 분석) (0) | 2021.03.03 |
[Data Structure] Linked List (연결 리스트) (0) | 2021.03.03 |
댓글을 사용할 수 없습니다.