[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 |