-
Notifications
You must be signed in to change notification settings - Fork 0
/
LinkedStack.h
146 lines (130 loc) · 3.48 KB
/
LinkedStack.h
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//! Tarefa de Estruturas de Dados - Pilha encadeada
/*
\author Alan Vinicius Cezar Ensina - Matrícula 16206354
\since 11/04/2018
\version 1.0
\copyright @ Alan Ensina
*/
#ifndef STRUCTURES_LINKED_STACK_H
#define STRUCTURES_LINKED_STACK_H
#include <cstdint>
#include <stdexcept>
namespace structures {
//! Template da classe da pilha encadeada
template<typename T>
class LinkedStack {
public:
//! Construtor padrão
LinkedStack() {
size_ = 0u;
top_ = nullptr;
}
//! Destrutor de objetos
~LinkedStack() {
clear();
}
//! Método que limpar a pilha encadeada
void clear() {
Node *atual, *anterior;
atual = top_;
while (atual != nullptr) {
anterior = atual;
atual = atual->next();
delete anterior;
}
size_ = 0u;
top_ = nullptr;
}
//! Método que insere um elemento no topo da pilha encadeada
void push(const T& data) {
if (empty()) {
Node *novoElemento = new Node(data, top_);
if (novoElemento == nullptr) {
throw std::out_of_range("Erro: a pilha está cheia!");
} else {
top_ = novoElemento;
size_ += 1;
}
} else {
Node *novoElemento;
novoElemento = new Node(data, top_);
if (novoElemento == nullptr) {
throw std::out_of_range("Erro: a pilha está cheia!");
} else {
top_ = novoElemento;
size_ += 1;
}
}
}
//! Método que retira um elemento da pilha encadeada
T pop() {
if (empty()) {
throw std::out_of_range("Erro: a pilha está vazia!");
} else if (size() == 1) {
Node* retirado = top_;
T valor = retirado->data();
top_ = nullptr;
delete retirado;
size_ -= 1;
return valor;
} else {
Node *retirado, *anterior;
T valor;
retirado = top_;
anterior = retirado->next();
valor = retirado->data();
top_ = anterior;
size_ -= 1;
delete retirado;
return valor;
}
}
//! Método que informa o elemento no topo da pilha
T& top() const {
if (empty()) {
throw std::out_of_range("Erro: a pilha está vazia!");
}
return top_->data();
}
//! Verifica se a pilha está vazia
bool empty() const {
return (size_ == 0u);
}
//! Informa o tamanho atual da pilha
std::size_t size() const {
return size_;
}
private:
class Node { // Elemento
public:
explicit Node(const T& data):
data_{data}
{}
Node(const T& data, Node* next):
data_{data},
next_{next}
{}
T& data() { // getter: dado
return data_;
}
const T& data() const { // getter const: dado
return data_;
}
Node* next() { // getter: próximo
return next_;
}
const Node* next() const { // getter const: próximo
return next_;
}
void next(Node* node) { // setter: próximo
next_ = node;
}
private:
T data_;
Node* next_;
};
Node* top_; // nodo-topo
std::size_t size_; // tamanho
};
} // namespace structures
#endif