此篇为本人自己学习过程中的笔记,有许多不足之处,仅供参考。
目录
1.栈的定义
栈是限定仅在表尾进行插入和删除操作的线性表,允许插入和删除操作的一端叫栈顶,另一端叫栈尾,不含任何数据元素的栈叫空栈。
对于栈来说,任何时候出栈的元素只能是栈顶元素,即最后入栈者最先出栈,栈中的元素除了具有线性关系,还具有先进后出(后进先出)的特性(简称LIFO结构)。使得栈成为程序设计中的有用工具。栈与一般线性表的区别仅是运算规则的不同。
如果问题的求解过程中有“后进先出”的天然特性,则求解的算法中必须要用到栈,例如,
数值转换 | 表达式求值 | 括号匹配的检验 | 八皇后问题 |
行编辑程序 | 函数调用 | 迷宫求解 | 递归调用的实现 |
2.栈的抽象数据类型定义
ADT Stack{
数据对象:
数据关系:
约定为栈顶,
为栈底。
基本操作:初始化、进栈、出栈、取栈顶元素等等
}ADT Stack
3.以C++类模板给出顺序栈的实现
顺序栈的储存方式同一般线性表的顺序储存结构完全相同,利用一组地址连续的储存单元,依次存放栈底到栈顶的元素,栈底一般在低地址端。
使用数组作为顺序栈储存的特点,方便,简单,但容易产生溢出(数组大小固定)
上溢(overflow):栈已满,又要压入元素
下溢(underflow):栈已空,还要弹出元素
注:上溢是一种错误,使问题的处理无法进行,下溢一般被认为是一种结束条件,即问题处理结束
3.1 栈的声明
template<class T>
class Stack
{
public: //操作
Stack(); //构造函数
~Stack(); // 析构函数
void DestroyStack(); //销毁栈
bool Empty(); //判断栈是否为空
void StackPush(T x); //入栈操作
void StackPop(); //出栈操作
void PrintStack(); //打印栈中元素
int StackLength(); //求出栈的长度
T GetTop(); //取栈顶元素
void ClearStack(); //将栈置空
public:
T* data; //指针 存储动态空间申请
int length; //栈的长度
};
3.2 栈的操作
3.2.1 构造与析构函数
MAXSIZE表示栈储存的最大空间,栈满时的处理方法,1.报错,返回操作系统。2.分配更大的空间,将原栈的数据移入新栈。
template<class T>
Stack<T>::Stack()
{
this->data = new T[MAXSIZE];
this->length = 0;
}
template<class T>
Stack<T>::~Stack()
{
delete [] data;
}
在构造函数中初始化栈,申请空间,并将长度设为0,即代表是空栈,在析构函数中回收空间。
3.2.2 判断栈是否为空
Empty
前置条件:栈已存在
输入:无
功能:判断栈是否为空
输出:栈为空返回1,否则返回0
后置条件:栈不变
template <class T>
bool Stack<T>::Empty()
{
if (this->length == 0)
{
cout << "栈为空" << endl;
return TRUE;
}
else
{
cout << "栈不为空" << endl;
return FALSE;
}
}
3.2.3 求栈长
Length
Stack前置条件:栈已存在
输入:无
功能:计算栈中的元素个数(栈长)
输出:返回栈中的元素个数
后置条件:栈不变
template<class T>
int Stack<T>::StackLength()
{
if (!this->data)
{
cout << "栈不存在" << endl;
return FALSE;
}
return this->length;
}
3.2.4 入栈操作
StackPush
前置条件:栈已存在
输入:元素值x
功能:在栈顶插入一个元素x
输出:返回栈中的元素个数
后置条件:如果插入成功,栈顶增加一个元素
template<class T>
void Stack<T>::StackPush(T x)
{
if (!this->data)
{
cout << "栈不存在" << endl;
return;
}
else if (this->length == MAXSIZE)
{
cout << "内存已满" << endl;
return;
}
else
{
this->data[this->length] = x;
this->length++;
}
}
3.2.5 出栈操作
StackPop
前置条件:栈已存在
输入:无
功能:删除栈顶元素x
输出:如果删除成功,返回删除元素;否则,抛出元素
后置条件:如果删除成功,栈顶减少一个元素
template<class T>
void Stack<T>::StackPop()
{
if (!this->data)
{
cout << "栈不存在" << endl;
return;
}
data[this->length--];
}
3.2.6 取当前栈顶元素
GetTop
前置条件:栈已存在
输入:无
功能:读取当前栈顶元素
输出:若栈不空,返回当前栈顶元素
后置条件:栈不变
template<class T>
T Stack<T>::GetTop()
{
if (!this->data)
{
cout << "栈不存在" << endl;
return FALSE;
}
return data[this->length - 1];
}
3.2.7 置空栈
ClearStack
前置条件:栈已存在
输入:无
功能:将栈置空
输出:无
后置条件:栈中无元素
template<class T>
void Stack<T>::ClearStack()
{
if (!this->data)
{
cout << "栈不存在" << endl;
return;
}
this->length = 0;
cout << "栈已经被清空" << endl;
}
3.2.8 打印栈中元素
PrintStack
前置条件:栈已存在
输入:无
功能:将栈中元素输出
输出:将栈中的元素从上至下输出
后置条件:栈不变
template<class T>
void Stack<T>::PrintStack()
{
if (!this->data)
{
cout << "栈不存在" << endl;
return;
}
cout << "top -->";
for (int i = length-1; i >= 0; i--)
cout << "\t|\t" <<data[i] << "\t|" << endl;
cout << "\t|---------------|" << endl;
}
3.2.9 销毁栈
DestroyStack
前置条件:栈已存在
输入:无
功能:销毁栈
输出:无
后置条件:释放栈原本占据的储存空间
template<class T>
void Stack<T>::DestroyStack()
{
if (!this->data)
{
cout << "栈不存在" << endl;
return;
}
this->data=NULL;
cout << "栈已销毁" << endl;
}
3.2.10 测试代码以及输出结果
int main()
{
Stack<int> s;
s.StackPush(1);
s.StackPush(2);
s.StackPush(3);
s.StackPush(4);
s.PrintStack();
cout << "栈的长度为:" << s.StackLength() << endl;
s.StackPop();
s.PrintStack();
cout << "栈的长度为:" << s.StackLength() << endl;
cout << "栈顶元素为:" << s.GetTop() << endl;
s.Empty();
s.ClearStack();
s.Empty();
s.DestroyStack();
system("pause");
return EXIT_SUCCESS;
}
输出结果:
3.2.11 完整代码 Stach.h与Stack.cpp
#pragma once
#define MAXSIZE 100
#define TRUE 1
#define FALSE 0
template<class T>
class Stack
{
public: //操作
Stack(); //构造函数
~Stack(); // 析构函数
void DestroyStack(); //销毁栈
bool Empty(); //判断栈是否为空
void StackPush(T x); //入栈操作
void StackPop(); //出栈操作
void PrintStack(); //打印栈中元素
int StackLength(); //求出栈的长度
T GetTop(); //取栈顶元素
void ClearStack(); //将栈置空
public:
T* data; //指针 存储动态空间申请
int length; //栈的长度
};
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include"Stack.h"
using namespace std;
template<class T>
Stack<T>::Stack()
{
this->data = new T[MAXSIZE];
this->length = 0;
}
template<class T>
Stack<T>::~Stack()
{
delete [] data;
}
template<class T>
void Stack<T>::DestroyStack()
{
if (!this->data)
{
cout << "栈不存在" << endl;
return;
}
this->data=NULL;
cout << "栈已销毁" << endl;
}
template <class T>
bool Stack<T>::Empty()
{
if (this->length == 0)
{
cout << "栈为空" << endl;
return TRUE;
}
else
{
cout << "栈不为空" << endl;
return FALSE;
}
}
template<class T>
void Stack<T>::StackPush(T x)
{
if (!this->data)
{
cout << "栈不存在" << endl;
return;
}
else if (this->length == MAXSIZE)
{
cout << "内存已满" << endl;
return;
}
else
{
this->data[this->length] = x;
this->length++;
}
}
template<class T>
void Stack<T>::PrintStack()
{
if (!this->data)
{
cout << "栈不存在" << endl;
return;
}
cout << "top -->";
for (int i = length-1; i >= 0; i--)
cout << "\t|\t" <<data[i] << "\t|" << endl;
cout << "\t|---------------|" << endl;
}
template<class T>
int Stack<T>::StackLength()
{
if (!this->data)
{
cout << "栈不存在" << endl;
return FALSE;
}
return this->length;
}
template<class T>
void Stack<T>::StackPop()
{
if (!this->data)
{
cout << "栈不存在" << endl;
return;
}
data[this->length--];
}
template<class T>
T Stack<T>::GetTop()
{
if (!this->data)
{
cout << "栈不存在" << endl;
return FALSE;
}
return data[this->length - 1];
}
template<class T>
void Stack<T>::ClearStack()
{
if (!this->data)
{
cout << "栈不存在" << endl;
return;
}
this->length = 0;
cout << "栈已经被清空" << endl;
}
int main()
{
Stack<int> s;
s.StackPush(1);
s.StackPush(2);
s.StackPush(3);
s.StackPush(4);
s.PrintStack();
cout << "栈的长度为:" << s.StackLength() << endl;
s.StackPop();
s.PrintStack();
cout << "栈的长度为:" << s.StackLength() << endl;
cout << "栈顶元素为:" << s.GetTop() << endl;
s.Empty();
s.ClearStack();
s.Empty();
s.DestroyStack();
system("pause");
return EXIT_SUCCESS;
}