本文主要是介绍数据结构探险(二)——栈,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
demo说明栈原理,其中放入char类型
- 先进后出(FILO)
- 栈顶 栈底
改造栈,使其适用于复杂数据类型Coordinate
#ifndef COORDINATE_H
#define COORDINATE_H
#include<ostream>
using namespace std;class Coordinate
{
public:Coordinate(int x=0, int y=0);//默认构造函数void printCoordinate();private:int m_iX;int m_iY;
};#endif // COORDINATE_H
#include"Coordinate.h"
#include<iostream>using namespace std;Coordinate::Coordinate(int x,int y)
{m_iX=x;m_iY=y;
}void Coordinate::printCoordinate()
{cout<<"("<<m_iX<<","<<m_iY<<")";
}
int main(void)
{MyStack *pStack = new MyStack(5);pStack->push(Coordinate(1,2));//底pStack->push(Coordinate(3,4));pStack->stackTraverse(true);cout<<"栈中元素个数:"<<pStack->stackLength()<<endl;MyStack *pStack1= new MyStack(5);pStack1->push('h');pStack1->push('l');pStack1->push('x');pStack1->stackTraverse(false);cout<<"栈中元素个数:"<<p1Stack->stackLength()<<endl;
}
改造为类栈模板,使其适用于任何数据类型
- 模板类myStack的类定义和函数定义要在一个文件尖中(这里放在mystack.h中)
- 加入
template<typename T> class MyStack
声明类模板 - 对每个类的成员函数
template<typename T> void MyStack<T>::stackTraverse(bool isFromButtom) {//... }
- 实例化时要写
MyStack<Coordinate> *pStack = new MyStack<Coordinate>(5);
cout<<m_pBuffer[i];
对于不同的数据类型 需要重载操作符cout
如何重载?声明:friend ostream &operator<<(ostream &out,Coordinate &coor);
函数体:ostream &operator<<(ostream &out,Coordinate &coor) { out<<"("<<coor.m_iX<<","<<coor.m_iY<<")"; return out; }
#ifndef MYSTACK_H_INCLUDED
#define MYSTACK_H_INCLUDED#include<iostream>using namespace std;template<typename T>
class MyStack
{
public:MyStack(int size); //分配内存初始栈空间。设定栈容量,栈顶~MyStack(); //回收站空间内存bool stackEmpty(); //判断栈是否为空,为空返回true,非空返回falsebool stackFull(); //判断栈是否已满,为满返回true,不满返回falsevoid 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;//释放内存数组,也可以继续指针指为null
}
template<typename T>
bool MyStack<T>::stackEmpty()
{if(0==m_iTop)//一个提高质量的小技巧,这样写比m_iTop==0 便于报错查找错误{return true;}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;//栈中元素是否有用用itop标记,置零表示在栈当中放的所有值无效,再放新值覆盖即可
}template<typename T>
int MyStack<T>::stackLength()
{return m_iTop;//itop即可反应元素个数,有五个时m itop=5
}template<typename T>
bool MyStack<T>::push(T elem)
{if(stackFull()){//入栈失败处理://1 throw//2 返回值设为bool push 失败 return flasereturn false;}m_pBuffer[m_iTop]=elem;//这里要注意,复杂数据类型m_iTop++;return true;
}template<typename T>
bool MyStack<T>::pop(T &elem)
{if(stackEmpty()){return false;}m_iTop--;//栈顶指向的总是一个空位置,是下一个要入栈的位置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];}}else{for(int i=m_iTop-1;i>=0;i--){cout<<m_pBuffer[i];}}
}#endif // MYSTACK_H_INCLUDED
#ifndef COORDINATE_H
#define COORDINATE_H
#include<ostream>
using namespace std;class Coordinate
{
public:friend ostream &operator<<(ostream &out,Coordinate &coor);Coordinate(int x=0, int y=0);//默认构造函数void printCoordinate();private:int m_iX;int m_iY;
};
Coordinate::Coordinate(int x,int y)
{m_iX=x;m_iY=y;
}void Coordinate::printCoordinate()
{cout<<"("<<m_iX<<","<<m_iY<<")";
}ostream &operator<<(ostream &out,Coordinate &coor)
{out<<"("<<coor.m_iX<<","<<coor.m_iY<<")";return out;
}
#endif // COORDINATE_H
int main(void)
{MyStack<Coordinate> *pStack = new MyStack<Coordinate>(5);pStack->push(Coordinate(1,2));//底pStack->push(Coordinate(3,4));pStack->stackTraverse(true);cout<<"栈中元素个数:"<<pStack->stackLength()<<endl;MyStack<char> *pStack1= new MyStack<char>(5);pStack1->push('h');pStack1->push('l');pStack1->push('x');pStack1->stackTraverse(false);cout<<"栈中元素个数:"<<pStack1->stackLength()<<endl;
}
栈应用(一):数值转换
#include<stdlib.h>
#include<iostream>
#include"MyStack.h"
using namespace std;#define BINARY 2
#define OCTONARY 8
#define HEXADECIMAL 16int main(void)
{char num[]="0123456789ABCDEF";MyStack<int> *pStack = new MyStack<int>(30);int N= 1348;int mod=0;//存余数while(N!=0){mod = N % HEXADECIMAL;pStack->push(mod);N = N/HEXADECIMAL;}//如何打印出栈里面的内容//方法一:从顶往底遍历//pStack->stackTraverse(false);//方法二:避免了十六进制中无法输出ABCDEF的问题/*for(int i=pStack->stackLength()-1;i>=0;i--){num[pStack[i]];//无法用pStack[i]的方式获得元素,需要重载符号[]}*///方法三:使用popint elem=0;while(!pStack->stackEmpty()){pStack->pop(elem);cout<<num[elem];}delete pStack;pStack=NULL;system("pause");return 0;
}
1348的十六进制数为:
栈应用(二):括号匹配
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include"MyStack.h"
using namespace std;int main(void)
{MyStack<char> *pStack = new MyStack<char>(30);MyStack<char> *pNeedStack = new MyStack<char>(30);char str[]="[()]]";//char str[]="[[()]]";//记录当前需要的字符char currentNeed =0;//扫描str字符串for(int i=0;i<strlen(str);i++){//与当前需要的字符对比//不匹配的情况if(str[i]!=currentNeed){pStack->push(str[i]);switch(str[i]){case '['://case 只能是int 或者charif(currentNeed!=0){pNeedStack->push(currentNeed);}currentNeed=']';break;case '(':if(currentNeed!=0){pNeedStack->push(currentNeed);}currentNeed=')';break;default://如果字符是额外的])。一定不匹配 例如[()]]]]]的情况cout<<"字符串括号不匹配"<<endl;system("pause");return 0;}}//匹配的情况else{char elem;pStack->pop(elem);if(!pNeedStack->pop(currentNeed)){currentNeed=0;};}}//栈中是否还有字符(未必绝对,所以需要上述的default)if(pStack->stackEmpty()){cout<<"字符串括号匹配"<<endl;}else{cout<<"字符串括号不匹配"<<endl;}delete pStack;pStack= NULL;delete pNeedStack;pStack= NULL;system("pause");return 0;
}
测试:
这篇关于数据结构探险(二)——栈的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!