Skip to content

Commit

Permalink
[Stack] Apply template
Browse files Browse the repository at this point in the history
  • Loading branch information
deunlee committed May 31, 2020
1 parent 48364ef commit 1837e1d
Show file tree
Hide file tree
Showing 11 changed files with 420 additions and 132 deletions.
85 changes: 85 additions & 0 deletions Stack/ArrayStack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#ifndef __DEUN_ARRAY_STACK_H__
#define __DEUN_ARRAY_STACK_H__

#include "Stack.hpp"

namespace Deun {
/**
* 스택 클래스 (배열 기반)
*/
template <typename T>
class ArrayStack : public Stack<T> {
private:
int size; // 스택의 최대 크기 (메모리 할당량)
T* array; // 데이터 저장을 위한 배열
// top은 Stack 인터페이스의 count 변수를 사용함.
// count라고 명명한 이유는 LinkedListStack에서도 사용하기 위해서임.

public:
/**
* 스택 생성자
* @param {int} size 스택의 최대 크기
* @throw {StackError}
*/
ArrayStack(int size = 1000);

/**
* 스택 소멸자
*/
~ArrayStack();

/**
* 스택의 최대 크기를 반환합니다.
* @return {int}
*/
int getSize();

/**
* 현재 스택에 들어있는 원소의 개수를 반환합니다.
* @return {int}
*/
int getCount();

/**
* 스택이 비어있는지의 여부를 반환합니다.
* @return {bool}
*/
bool isEmpty();

/**
* 스택이 가득 차있는지의 여부를 반환합니다.
* @return {bool}
*/
bool isFull();

/**
* 스택에 원소를 삽입하고 성공 여부를 반환합니다.
* @param {T} element 원소
* @return {bool}
*/
bool push(const T& element);

/**
* 스택에서 마지막 원소를 반환하고 삭제합니다.
* @return {T}
* @throw {StackError}
*/
T pop();

/**
* 스택에서 마지막 원소를 반환합니다.
* pop()과 다르게 원소를 삭제하지 않습니다.
* @return {T}
* @throw {StackError}
*/
const T& peek();

/**
* 스택을 초기화합니다.
* 모든 원소가 삭제됩니다.
*/
void clear();
};
}

#endif
78 changes: 78 additions & 0 deletions Stack/ArrayStack.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#ifndef __DEUN_ARRAY_STACK_HPP__
#define __DEUN_ARRAY_STACK_HPP__

#include "ArrayStack.h"

namespace Deun {
template <typename T>
ArrayStack<T>::ArrayStack(int size) : Stack(0), size(size) {
if (size <= 0) {
throw StackError::SIZE_IS_TOO_SMALL;
}

array = new (std::nothrow) T[size];
if (!array) {
throw StackError::MEMORY_ALLOCATION_FAILED;
}
}

template <typename T>
ArrayStack<T>::~ArrayStack() {
delete[] array;
}

template <typename T>
int ArrayStack<T>::getSize() {
return size;
}

template <typename T>
int ArrayStack<T>::getCount() {
return count;
}

template <typename T>
bool ArrayStack<T>::isEmpty() {
return (count == 0); // count는 top 용도로 쓰임.
}

template <typename T>
bool ArrayStack<T>::isFull() {
return (count == size);
}

template <typename T>
bool ArrayStack<T>::push(const T& element) {
if (isFull()) {
return false;
}

array[count++] = element;
return true;
}

template <typename T>
T ArrayStack<T>::pop() {
if (isEmpty()) {
throw StackError::ELEMENT_NOT_FOUND;
}

return array[--count];
}

template <typename T>
const T& ArrayStack<T>::peek() {
if (isEmpty()) {
throw StackError::ELEMENT_NOT_FOUND;
}

return array[count - 1];
}

template <typename T>
void ArrayStack<T>::clear() {
count = 0;
}
}

#endif
84 changes: 84 additions & 0 deletions Stack/LinkedListStack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#ifndef __DEUN_LINKED_LIST_STACK_H__
#define __DEUN_LINKED_LIST_STACK_H__

#include "Stack.hpp"

namespace Deun {
/**
* 스택 노드
*/
template <typename T>
struct StackNode {
T data;
StackNode* next;
};

/**
* 스택 클래스 (연결 리스트 기반)
*/
template <typename T>
class LinkedListStack : public Stack<T> {
private:
StackNode<T>* head; // 첫 번째 노드를 가리키는 포인터

public:
/**
* 스택 생성자
*/
LinkedListStack();

/**
* 스택 소멸자
*/
~LinkedListStack();

/**
* 현재 스택에 들어있는 원소의 개수를 반환합니다.
* @return {int}
*/
int getCount();

/**
* 스택이 비어있는지의 여부를 반환합니다.
* @return {bool}
*/
bool isEmpty();

/**
* 스택이 가득 차있는지의 여부를 반환합니다.
* 연결 리스트로 구현된 스택에서는 항상 false를 반환합니다.
* @return {bool}
*/
bool isFull();

/**
* 스택에 원소를 삽입하고 성공 여부를 반환합니다.
* @param {T} element 원소
* @return {bool}
*/
bool push(const T& element);

/**
* 스택에서 마지막 원소를 반환하고 삭제합니다.
* @return {T}
* @throw {StackError}
*/
T pop();

/**
* 스택에서 마지막 원소를 반환합니다.
* pop()과 다르게 원소를 삭제하지 않습니다.
* @return {T}
* @throw {StackError}
*/
const T& peek();

/**
* 스택을 초기화합니다.
* 모든 원소가 삭제됩니다.
*/
void clear();
};
}

#endif
82 changes: 82 additions & 0 deletions Stack/LinkedListStack.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#ifndef __DEUN_LINKED_LIST_STACK_HPP__
#define __DEUN_LINKED_LIST_STACK_HPP__

#include "LinkedListStack.h"

namespace Deun {
template <typename T>
LinkedListStack<T>::LinkedListStack() : Stack(0), head(nullptr) {}

template <typename T>
LinkedListStack<T>::~LinkedListStack() {
clear();
}

template <typename T>
int LinkedListStack<T>::getCount() {
return count;
}

template <typename T>
bool LinkedListStack<T>::isEmpty() {
return (count == 0);
}

template <typename T>
bool LinkedListStack<T>::isFull() {
return false; // 연결 리스트로 구현한 스택은 한계가 없다고 가정한다.
}

template <typename T>
bool LinkedListStack<T>::push(const T& element) {
// 스택의 맨 앞에 노드를 삽입한다.
StackNode<T>* front = new (std::nothrow) StackNode<T>;
if (!front) {
return false;
}
front->data = element;
front->next = head;
head = front;
count++;
return true;
}

template <typename T>
T LinkedListStack<T>::pop() {
// 스택의 맨 앞 노드를 반환하고 삭제한다.
if (isEmpty()) {
throw StackError::ELEMENT_NOT_FOUND;
}

StackNode<T>* front = head;
T data = front->data;
head = front->next;
delete front;
count--;
return data;
}

template <typename T>
const T& LinkedListStack<T>::peek() {
if (isEmpty()) {
throw StackError::ELEMENT_NOT_FOUND;
}

return head->data;
}

template <typename T>
void LinkedListStack<T>::clear() {
StackNode<T>* front = head;
StackNode<T>* next;
while (front) {
next = front->next;
delete front;
front = next;
}
head = nullptr;
count = 0;
}
}

#endif
34 changes: 0 additions & 34 deletions Stack/Main.cpp

This file was deleted.

Loading

0 comments on commit 1837e1d

Please sign in to comment.