栈的逻辑结构
栈(stack)是限定仅在表的一端进行插入和删除操作的线性表,允许插入和删除的一端称为栈顶(stack top),另一端称为栈底(stack bottom),不含任何数据元素的栈称为空栈。
如图所示,栈中有三个元素,插入元素(也称入栈、进栈、压栈)的顺序是a1,a2,a3。当需要删除元素(也称出栈、弹栈)时只能先删除a3。换言之,任何时刻出栈的元素都只能是栈顶元素,即最后入栈者最先出栈。所以栈中元素出了具有线性关系外,还具有后进先出(last in first out)的特性。
栈的顺序存储结构及实现
栈的顺序存储结构称为顺序栈(sequential stack)。顺序栈本质上是顺序表的简化,唯一需要确定的是用数组的哪一端表示栈底。通常把数组中下标为0的一端作为栈底,同时附设变量top指示栈顶元素在数组中的位置。
顺序栈的实现
顺序栈类的定义
const int StackSize = 10;
template <typename DataType>
class SeqStack{
public:
SeqStack(); //构造函数,初始化一个空栈
~SeqStack(); //析构函数
void Push(DataType x); //入栈操作,将元素x入栈
DataType Pop(); //出栈操作,将栈顶元素弹出
DataType GetTop(); //取栈顶元素,并不删除
int Empty(); //判断栈是否为空
private:
DataType data[StackSize]; //存放栈元素的数组
int top; //栈顶指针
}
成员函数的实现
template <typename DataType>
SeqStack<DataType>::SeqStack(){
top = -1;
}
template <typename DataType>
void SeqStack<DataType>::Push(DataType x){
if(top == StackSize-1) throw "上溢";
data[++top] = x;
}
template <typename DataType>
DataType SeqStack<DataType>::Pop(){
DataType x;
if(top == -1) throw "下溢";
x = data[top--];
return x;
}
template <typename DataType>
DataType SeqStack<DataType>::GetTop(){
DataType x;
if(top == -1) throw "下溢";
x = data[top];
return x;
}
template <typename DataType>
int SeqStack<DataType>::Empty(){
return top == -1;
}
栈的连接存储结构及实现
栈的连接存储结构称为链栈(linked stack),通常用单链表表示,其节点结构与单链表的结点结构相同。因为只能在栈顶执行插入和删除操作,显然以单链表的头部作栈顶是最方便的,而且没有必要像单链表那样为了运算方便附加头结点。其结构如下图所示。
链栈的实现
链栈类的定义
template <typename DataType>
struct Node
{
DataType data;
Node<DataType> *next;
};
template <typename DataType>
class LinkStack{
public:
LinkStack(); //构造函数,初始化一个空链栈
~LinkStack(); //析构函数,释放链栈各结点的存储空间
void Push(DataType x); //入栈操作,将元素x入栈
DataType Pop(); //出栈操作,将栈顶元素出栈
DataType GetTop(); //取栈顶元素,并不删除
int Empty(); //判空操作,判断链栈是否为空栈
private:
Node<DataType> *top;//栈顶指针
}
成员函数的实现
template <typename DataType>
LinkStack<DataType>::LinkStack(){
//由于链栈不带头结点,初始化一个空链栈只需将栈顶指针top置空
top = nullptr;
}
template <typename DataType>
LinkStack<DataType>::~LinkStack(){
Node<DataType> *p;
while(top != nullptr){
p = top;
top = top->next;
delete p;
}
}
template <typename DataType>
void LinkStack<DataType>::Push(DataType x){
Node<DataType> *s = nullptr;
s = new Node<DataType>;
s->data = x;
s->next = top;
top = s;
}
template <typename DataType>
DataType LinkStack<DataType>::Pop(){
Node<DataType> *p = nullptr;
DataType x;
if(top ==nullptr) throw "下溢";
x = top->data;
p = top;
top = top->next;
delete p;
return x;
}
template <typename DataType>
DataType LinkStack<DataType>::GetTop(){
if(top ==nullptr) throw "下溢";
return top->data;
}
template <typename DataType>
int LinkStack<DataType>::Empty(){
return top == nullptr;
}