1. 栈的基本概念
栈是限定只在表头进行插入(入栈)和删除(出栈)操作的线性表,表头端称为栈顶,表尾端称为栈底。
设有栈
则一般称
为栈底元素,
为栈顶元素,按
的顺序依次进栈,出栈的第一个元素为栈顶元素,也就是说栈是按照后进先出的原则进行。
栈的实现和线性表类似,有两种方法——顺序栈和链栈
2. 顺序栈
//.hpp文件
#pragma once
#define DEFAULT_SIZE 10
//顺序栈类
template<typename elemType>
class SqStack
{
private:
//顺序栈的数据成员
int count;
int maxSize;
elemType* elems;
//辅助函数
bool Full() const; //判断栈是否已满
void Init(int size);//对栈进行初始化
public:
//抽象数据类型方法声明及重载编译系统默认方法声明
SqStack(int size = DEFAULT_SIZE);//构造函数
virtual ~SqStack();//析构函数
int getLength() const;//求栈的长度
bool isEmpty() const;//判断栈是否为空
void Clear();//清空栈
void Traverse(void(*Visit)(elemType &));//遍历栈
bool Push(const elemType &e);//入栈
bool Top(elemType &e) const;//返回栈顶元素
bool Pop(elemType &e);//出栈
SqStack(SqStack<elemType> ©);//复制构造函数
SqStack<elemType>& operator=(SqStack<elemType> ©);//赋值运算符重载
};
//顺序栈的实现
template<typename elemType>
bool SqStack<elemType>::Full() const
{
return count == maxSize;
}
template<typename elemType>
void SqStack<elemType>::Init(int size)
{
maxSize = size;
if (elems != NULL) delete[] elems;
elems = new elemType[maxSize];
count = 0;
}
template<typename elemType>
SqStack<elemType>::SqStack(int size = DEFAULT_SIZE)
{
elems = NULL;
Init(size);
}
template<typename elemType>
SqStack<elemType>::~SqStack()
{
if (elems != NULL) delete[] elems;
}
template<typename elemType>
int SqStack<elemType>::getLength() const
{
return count;
}
template<typename elemType>
bool SqStack<elemType>::isEmpty() const
{
return count == 0;
}
template<typename elemType>
void SqStack<elemType>::Clear()
{
count = 0;
}
template<typename elemType>
void SqStack<elemType>::Traverse(void(*Visit)(elemType &))
{
for (int curPosition = 1; curPosition <= this->getLength(); curPosition++)
{
(*Visit)(elems[curPosition - 1]);
}
}
template<typename elemType>
bool SqStack<elemType>::Push(const elemType &e)
{
if (Full())
{
return false;
}
else
{
elems[count++] = e;
return true;
}
}
template<typename elemType>
bool SqStack<elemType>::Top(elemType &e) const
{
if (isEmpty())
{
return false;
}
else
{
e = elems[count - 1];
return true;
}
}
template<typename elemType>
bool SqStack<elemType>::Pop(elemType &e)
{
if (isEmpty())
{
return false;
}
else
{
e = elems[--count];
return true;
}
}
template<typename elemType>
SqStack<elemType>::SqStack(SqStack<elemType> ©)
{
elems = NULL;
Init(copy.maxSize);//这里为什么可以直接访问私有成员maxSize
count = copy.getLength();
for (int curPosition = 1; curPosition <= count; curPosition++)
{
elems[curPosition - 1] = copy.elems[curPosition - 1];
}
}
template<typename elemType>
SqStack<elemType>& SqStack<elemType>::operator =(SqStack<elemType> ©)
{
if (© != this)
{
Init(copy.maxSize);
count = copy.getLength();
for (int curPosition = 1; curPosition <= count; curPosition++)
{
elems[curPosition - 1] = copy.elems[curPosition - 1];
}
}
return *this;
}
//测试文件
#include <iostream>
#include "SqStack.hpp"
using namespace std;
template<typename elemType>
void Visit2(elemType &e)
{
cout << e << endl;
}
int main(int argc, char* argv[])
{
SqStack<int> mySqStack;
mySqStack.Push(1);
mySqStack.Push(2);
mySqStack.Traverse(Visit2);//使用函数指针!!!
SqStack<int> mySqStack1(mySqStack);
mySqStack1.Traverse(Visit2);
getchar();
return 0;
}
3. 链表栈
在程序中同时使用多个栈的情形下,使用链式栈不但可以提高存储效率,同时还可以达到共享存储空间的目的。(如何达到共享存储空间的目的?)
//.hpp文件
#pragma once
//节点类
template<typename elemType>
struct Node
{
//数据成员
elemType data;//数据域
Node<elemType>* next;//指针域
//构造函数
Node();//无参构造函数
Node(elemType item, Node<elemType>* Link = NULL);//已知数据域和指针域建立结构
};
//节点类的实现部分
template<typename elemType>
Node<elemType>::Node()
//操作结果:构造指针域为空的节点
{
this->next = NULL;
}
template<typename elemType>
Node<elemType>::Node(elemType item, Node<elemType>* Link)
//操作结果:构造数据域为item指针域为Link的节点
{
this->data = item;
this->next = Link;
}
//链栈类
template<typename elemType>
class LinkStack
{
private:
//链栈实现的数据成员
Node<elemType>* top;//栈顶指针
//辅助函数
void Init();//初始化栈
public:
//抽象数据类型方法声明及重载编译系统默认方法声明
LinkStack();//无参构造函数
virtual ~LinkStack();//析构函数
int getLength() const;//获取栈的长度
bool isEmpty() const;//判断栈是否为空
void Clear();//将栈清空
void Traverse(void(*Visit)(elemType &e));//遍历栈
bool Push(const elemType & e);//入栈
bool Top(elemType& e) const;//返回栈顶的元素
bool Pop(elemType& e);//出栈
LinkStack(LinkStack<elemType> & copy);//复制构造函数
LinkStack<elemType>& operator=(LinkStack<elemType> & copy);//重载赋值运算符
};
//链栈类的实现
template<typename elemType>
void LinkStack<elemType>::Init()
//对链栈进行初始化,外部不可调用
{
top = NULL;
}
template<typename elemType>
LinkStack<elemType>::LinkStack()
{
Init();
}
template<typename elemType>
LinkStack<elemType>::~LinkStack()
{
Clear();
}
template<typename elemType>
int LinkStack<elemType>::getLength() const
{
int count = 0;
for (Node<elemType>* curPosition = top; curPosition != NULL; curPosition = curPosition->next)
{
count++;
}
return count;
}
template<typename elemType>
bool LinkStack<elemType>::isEmpty() const
{
return top == NULL;
}
template<typename elemType>
void LinkStack<elemType>::Clear()
{
elemType e;
while (top != NULL)
{
Pop(e);//删除链表元素的技巧
}
}
template<typename elemType>
void LinkStack<elemType>::Traverse(void(*Visit)(elemType &e))
{
for (Node<elemType>* curPosition = top; curPosition != NULL; curPosition = curPosition->next)
{
(*Visit)(curPosition->data);
}
}
template<typename elemType>
bool LinkStack<elemType>::Push(const elemType & e)
{
Node<elemType>* tempNode = top;
top = new Node < elemType > ;
if (top == NULL)//如果动态内存耗尽
{
return false;
}
top->data = e;
top->next = tempNode;
return true;
}
template<typename elemType>
bool LinkStack<elemType>::Top(elemType& e) const
{
if (isEmpty())
{
return false;
}
else
{
e = top->data;
return true;
}
}
template<typename elemType>
bool LinkStack<elemType>::Pop(elemType& e)
{
if (isEmpty())
{
return false;
}
else
{
e = top->data;
Node<elemType>* tempPtr = top;
top = top->next;
delete tempPtr;
return true;
}
}
template<typename elemType>
LinkStack<elemType>::LinkStack(LinkStack<elemType> & copy)
{
if (copy.isEmpty())
{
Init();
}
else
{
top = new Node<elemType>(copy.top->data);
Node<elemType>* tempPtr = top;
for (Node<elemType>* curPosition = copy.top->next; curPosition != NULL; curPosition = curPosition->next)
{
tempPtr->next = new Node<elemType>(curPosition->data);
tempPtr = tempPtr->next;
}
}
}
template<typename elemType>
LinkStack<elemType>& LinkStack<elemType>::operator=(LinkStack<elemType> & copy)
{
if (© != this)
{
if (copy.isEmpty())
{
Init();
}
else
{
Clear();
top = new Node<elemType>(copy.top->data);
Node<elemType>* tempPtr = top;
for (Node<elemType>* curPosition = copy.top->next; curPosition != NULL; curPosition = curPosition->data)
{
tempPtr->next = new Node<elemType>(copy.top->data);
tempPtr = tempPtr->next;
}
}
}
return *this;
}
//测试文件
#include "LinkStack.hpp"
#include <iostream>
using namespace std;
template<typename elemType>
void Visit2(elemType &e)
{
cout << e << endl;
}
int main(int argc, char* argv[])
{
LinkStack<int> myLinkStack;
using namespace std;
myLinkStack.Push(1);
myLinkStack.Push(2);
myLinkStack.Push(3);
myLinkStack.Traverse(Visit2);//使用函数指针!!!
LinkStack<int> mySqStack1(myLinkStack);
mySqStack1.Traverse(Visit2);
getchar();
return 0;
}