数据结构与算法学习笔记——栈ADT C++实现
1 特点
栈的数据结构为线性结构
栈只能在同一位置进行插入和删除,这个位置叫做栈顶。后进先出(LIFO),生活中的例子有坐电梯、去西红门绞肉机坐地铁
2 包含的操作
- 入栈(压栈)
- 出栈(弹出)
- 读栈顶元素
3 实现方式
3.1 基于数组实现(应用较多)
基于数组实现(非vector)的空间是静态的,空间不能再扩展,因此会出现空间不够的情况;但是从ADT角度出发不会有空间不够的情况,空间不够属于实现时的限制
编程时要考虑指针移动操作与数据操作时的顺序,以及空间是否为满/空
Stack.h
#include <iostream>
const int MAX = 10; // 数组大小
template <typename T>
class Stack
{
public:
Stack();
~Stack();
void push(T);
T pop();
T top();
private:
int _pointer;
T _array[MAX] = {0}; // 数据放在数组中
protected:
};
Stack.cpp
#include "Stack.h"
/*
* 令pointer=-1,表示空栈
*/
template <typename T>
Stack<T>::Stack()
{
_pointer = -1;
}
/*
* 析构函数
*/
template <typename T>
Stack<T>::~Stack()
{
}
/*
* 入栈
* 从ADT角度出发没有空间不够的情况,但这里的具体实现还是把这个情况纳入了考虑
*/
template <typename T>
void Stack<T>::push(T data)
{
if(_pointer < MAX-1)
_array[++_pointer] = data;
else
std::cout << "the array is full, failed to push" << std::endl;
}
/*
* 出栈
* 如果在栈为空的情况下出栈,返回值为-1并报错
*/
template <typename T>
T Stack<T>::pop()
{
T temp;
if(_pointer > -1)
{
temp = _array[_pointer];
_array[_pointer] = 0; // 这里用元素==0表示删除
_pointer--;
}
else
{
temp = -1;
std::cout << "the stack is empty, failed to pop" << std::endl;
}
return temp;
}
/*
* 读栈顶元素
*/
template <typename T>
T Stack<T>::top()
{
if(_pointer > -1)
{
return _array[_pointer];
}
else
{
std::cout << "the stack is empty" << std::endl;
return T(-1);
}
}
template class Stack<int>;
template class Stack<float>;
template class Stack<double>;
main.cpp
#include <iostream>
#include "Stack.h"
int main()
{
Stack<int> stack1;
for(int i = 0; i < MAX + 1; i++)
{
int data;
std::cout << "input the number you want to push:" << std::endl;
std::cin >> data;
stack1.push(data);
}
std::cout << "top a number, the number is: " << stack1.top() << std::endl;
for(int i = 0; i < MAX + 1; i++)
{
std::cout << "pop a number, the number is: " << stack1.pop() << std::endl;
}
return 0;
}
运行结果:
3.2 基于单链表实现
链表需要有表头,编程时注意给表头赋值
Stack.h
#include <iostream>
template <typename T>
struct list
{
T data;
list *next;
};
template <typename T>
class Stack
{
public:
Stack();
~Stack();
void push(T);
T pop();
T top();
private:
list<T> *_pointer;
list<T> *_head;
protected:
};
Stack.cpp
#include "Stack.h"
/*
* pointer==NULL时说明为空栈
*/
template <typename T>
Stack<T>::Stack()
{
_head = _pointer = NULL;
}
/*
* 析构函数
*/
template <typename T>
Stack<T>::~Stack()
{
list<T> *p1, *p2;
p1 = p2 = _head;
for(;p1 != NULL;)
{
p1 = p1->next;
delete p2;
p2 = p1;
}
}
/*
* 入栈
*/
template <typename T>
void Stack<T>::push(T data)
{
list<T> *p = _pointer;
_pointer = new list<T>;
_pointer->data = data;
_pointer->next = NULL;
if(p == NULL)
{
_head = _pointer;
}
else
{
p->next = _pointer;
}
}
/*
* 出栈
* 如果在栈为空的情况下出栈,返回值为-1并报错
*/
template <typename T>
T Stack<T>::pop()
{
T temp;
if(_pointer == NULL)
{
_head = NULL;
std::cout << "the stack is empty, failed to pop" << std::endl;
temp = -1;
}
else if(_pointer == _head)
{
temp = _pointer->data;
delete _pointer;
_pointer = _head = NULL;
}
else
{
temp = _pointer->data;
list<T> *p;
for(p = _head; p->next != _pointer; p = p->next)
;
delete _pointer;
_pointer = p;
_pointer->next = NULL;
}
return temp;
}
/*
* 读栈顶元素
*/
template <typename T>
T Stack<T>::top()
{
if(_pointer == NULL)
{
std::cout << "the stack is empty" << std::endl;
return T(-1);
}
else
{
return _pointer->data;
}
}
template class Stack<int>;
template class Stack<float>;
template class Stack<double>;
main.cpp
#include <iostream>
#include "Stack.h"
int main()
{
Stack<int> stack1;
for(int i = 0; i < 5; i++)
{
int data;
std::cout << "input the number you want to push:" << std::endl;
std::cin >> data;
stack1.push(data);
}
std::cout << "top a number, the number is: " << stack1.top() << std::endl;
for(int i = 0; i < 6; i++)
{
std::cout << "pop a number, the number is: " << stack1.pop() << std::endl;
}
return 0;
}
运行结果: