栈
栈是一种特殊的线性表,只允许在表的一端进行插入或者删除操作。有栈顶(top)和栈底(bottom),无数据时叫空栈,插入(push)操作称“进栈“,”压栈”,删除(pop)操作称“退栈”,”出栈“
栈机制 后进先出(LIFO)
栈要素 栈底(为0),栈顶(出入栈被处理的)
存储结构
顺序存储(顺序栈):地址连续的存储单元依次存放自栈底到栈顶,栈底不变,栈顶移动。
链式存储(链式栈):由节点构成的单链表实现,插入和删除操作只能在链表头进行。无头节点的单链表,无栈满问题,可扩充。
栈实现
template<typename T>
class MyStack
{
public:
MyStack(int szie); //分配内存初始化栈空间,设定栈容量,栈顶
~MyStack(); //回收栈空间内存
bool stackEmpty(); //判定栈是否为空
bool stackFull(); //判定栈是否为满
void clearStack(); //清空栈
int stackLength(); //已有元素的个数
bool push(T elem); //元素入栈,栈顶上升
bool pop(T &elem); //元素出栈,栈顶下降
void stackTraverse(bool isFromButtom); //遍历栈中所有元素
private:
T *m_pBuffer; //栈空间指针,类型要与数据的类型一致
int m_iSize; //栈容量
int m_iTop; //栈顶,栈中元素个数
};
template<typename T>
MyStack<T>::MyStack(int size){
m_iSize = size;
m_pBuffer = new T[size];
m_iTop = 0;
}
template<typename T>
MyStack<T>::~MyStack(){
delete[]m_pBuffer;
}
template<typename T>
bool MyStack<T>::stackEmpty(){
if (m_iTop == 0) //if(0==m_iTop)漏写=系统会报错
return true;
else
return false;
}
template<typename T>
bool MyStack<T>::stackFull(){
if (m_iTop >= m_iSize)
return true;
return false;
}
template<typename T>
void MyStack<T>::clearStack(){
m_iTop = 0;
}
template<typename T>
int MyStack<T>::stackLength(){
return m_iTop;
}
template<typename T>
bool MyStack<T>::push(T elem){
if (stackFull())
return false; //或者可以throw抛异常,throw 1;
m_pBuffer[m_iTop++] = elem;//m_iTop指向的总是下一位(空位)
return true;
}
template<typename T>
bool MyStack<T>::pop(T &elem){ //main里申请该类型的变量,传入参数引用来得到栈顶元素值
if (stackEmpty())
return false;
elem = m_pBuffer[--m_iTop];//栈顶先减,才能去到元素
return true;
}
template<typename T>
void MyStack<T>::stackTraverse(bool isFromButtom){ //由参数控制遍历方式
if (isFromButtom){ //从栈底开始
for (int i = 0; i < m_iTop; i++){
cout << m_pBuffer[i]<<" ";
//m_pBuffer[i].printCoordinate();//当数据类型为对象,使用对象的输出函。使用模板类时,对象要做输出运算符重载
}
}
else{ //从栈顶开始
for (int i = m_iTop - 1; i >= 0; i--){
cout << m_pBuffer[i];
//m_pBuffer[i].printCoordinate();
}
}
}
应用
MyStack<int> *pStack=new MyStack<int>(5);//指定数据类型
MyStack<Coordinate> *pStack=new MyStack<Coordinate>(5);
栈用于进制转换
char num[]="0123456789abcdef";//十六进制的下标索引
MyStack<int> *pStack=new MyStack<int>(20);
int N,mod=0;
cin<<N;
while(N!=0){
mod=N%2;//8,16
pStack->push(mod);//从栈顶插入余数
N/=2;
}
//pStack->stackTraverse(false);从栈顶遍历,16进制不可用
int element=0;
while(!pStack->stackEmpty()){
pStack->pop(element);
cout<<num[element];//出栈元素作为索引
}
delete pStack;
pStack=NULL;
return 0;
括号匹配
MyStack<char> *pStack = new MyStack<char>(30);//存放用于匹配的元素
MyStack<char> *pNeedStack = new MyStack<char>(30);//存放需要匹配的元素
char str[] = "[[()]]";
char currentNeed = 0;
for (int i = 0; i<strlen(str); i++){
if (str[i] != currentNeed){
pStack->push(str[i]);
switch (str[i]){
case '[':
if (currentNeed != 0){ //如果当前需要的已有,先入栈
pNeedStack->push(currentNeed);
}
currentNeed = ']';
break;
case '(':
if (currentNeed != 0){
pNeedStack->push(currentNeed);
}
currentNeed = ')';
break;
default:
cout << "字符串括号不匹配" << endl;//避免因后方多括号而未入栈(栈已经空了)的情况
return 0;
}
}
else{ //匹配成功
char elem;
pStack->pop(elem);
if (!pNeedStack->pop(currentNeed)){
currentNeed = 0;
}
}
}
if (pStack->stackEmpty()){
cout << "字符串括号匹配" << endl;
}
else{
cout << "字符串括号不匹配" << endl;
}
delete pStack;
pStack = NULL;
delete pNeedStack;
pNeedStack = NULL;