自家写的栈,目前只有初始化,出栈,入栈操作,因为结构知道,栈顶元素可以自己看
一:顺序栈
#include <bits/stdc++.h>
#define ref1(i,s,e,c) for(int i=s;i<e;i=i+c)
#define ref2(i,s,e,c) for(int i=s;i<=e;i=i+c)
#define ref3(i,e,s,c) for(int i=e;i>=s;i=i-c)
using namespace std;
typedef long long ll;
const int MAXSIZE=1000010;
typedef int ElemType;
typedef struct {
ElemType elem[MAXSIZE];
int top;
}stack;
void initStack(stack *st){
st->top=-1;
}
void push(stack *st,ElemType x){
if(st->top<MAXSIZE-1){
st->top++;
st->elem[st->top]=x;
}
else{
cout<<"Overflow!\n";
}
}
ElemType pop(stack *st){
if(st->top==-1){
cout<<"underflow!\n";
return -1;
}
else{
ElemType x=st->elem[st->top];
st->top--;
return x;
}
}
int main()
{
return 0;
}
二、两个栈共用一向量
特点:栈底在两端,栈顶浮动,俩栈顶相遇时栈满
#include <bits/stdc++.h>
#define ref1(i,s,e,c) for(int i=s;i<e;i=i+c)
#define ref2(i,s,e,c) for(int i=s;i<=e;i=i+c)
#define ref3(i,e,s,c) for(int i=e;i>=s;i=i-c)
using namespace std;
typedef long long ll;
const int MAXSIZE=1000010;
typedef int ElemType;
typedef struct {
ElemType elem[MAXSIZE];
int top[2];
}DupStack;
int d[2]={-1,MAXSIZE};//左右栈判断栈空的条件
int z[2]={1,-1};//左右栈进栈时栈顶指针的增量
void initStack(DupStack *st,int i){
st->top[i]=d[i];
}
void push(DupStack *st,ElemType x,int i){
if(st->top[1]!=st->top[0]+1){
st->top[i]+=z[i];
st->elem[st->top[i]]=x;
}
else{
cout<<"Overflow!\n";
}
}
ElemType pop(DupStack *st,int i){
if(st->top[i]==d[i]){
cout<<"underflow!\n";
return -1;
}
else{
ElemType x=st->elem[st->top[i]];
st->top[i]-=z[i];
return x;
}
}
int main()
{
return 0;
}
三、链表存储栈
#include <bits/stdc++.h>
#define ref1(i,s,e,c) for(int i=s;i<e;i=i+c)
#define ref2(i,s,e,c) for(int i=s;i<=e;i=i+c)
#define ref3(i,e,s,c) for(int i=e;i>=s;i=i-c)
using namespace std;
typedef long long ll;
const int MAXSIZE=1000010;
typedef int ElemType;
typedef struct Lsnode{
ElemType elem;
Lsnode *next;
}Lsnode;
Lsnode *top;
void initStack(Lsnode *top){
top->next=NULL;
}
void push(Lsnode *top,ElemType x){
Lsnode *p=(Lsnode*)malloc(sizeof(Lsnode));
p->elem=x;
p->next=top->next;
top->next=p;
}
ElemType pop(Lsnode *top){
if(top->next==NULL){
cout<<"Underflow!\n";
return -1;
}
else{
Lsnode *p=top->next;
top->next=p->next;
ElemType x=p->elem;
free(p);
return x;
}
}
int main()
{
top=(Lsnode*)malloc(sizeof(Lsnode));
initStack(top);
return 0;
}
四、多链表栈
特点:将多个链表的指针放入一个一维数组之中
#include <bits/stdc++.h>
#define ref1(i,s,e,c) for(int i=s;i<e;i=i+c)
#define ref2(i,s,e,c) for(int i=s;i<=e;i=i+c)
#define ref3(i,e,s,c) for(int i=e;i>=s;i=i-c)
using namespace std;
typedef long long ll;
const int MAXSIZE=1000010;
typedef int ElemType;
typedef struct Lsnode{
ElemType elem;
Lsnode *next;
}Lsnode;
Lsnode *top[MAXSIZE];//指针数组
void initStack(Lsnode *top[]){
ref1(i,0,MAXSIZE,1)
top[i]->next=NULL;
}
void push(Lsnode *top[],ElemType x,int i){
Lsnode *p=(Lsnode*)malloc(sizeof(Lsnode));
p->elem=x;
p->next=top[i]->next;
top[i]->next=p;
}
ElemType pop(Lsnode *top[],int i){
if(top[i]->next==NULL){
cout<<"Underflow!\n";
return -1;
}
else{
Lsnode *p=top[i]->next;
top[i]->next=p->next;
ElemType x=p->elem;
free(p);
return x;
}
}
int main()
{
initStack(top);
return 0;
}
栈的应用:
一、表达式的计算
我用C++自带的栈写
#include <bits/stdc++.h>
#define ref1(i,s,e,c) for(int i=s;i<e;i=i+c)
#define ref2(i,s,e,c) for(int i=s;i<=e;i=i+c)
#define ref3(i,e,s,c) for(int i=e;i>=s;i=i-c)
using namespace std;
typedef long long ll;
const int MAXSIZE=1000010;
map<char,int> Map;//将算符转化为数字
stack<int> num;//存放数字的栈
stack<char> ch;//存放算符的栈
/*
算符之间的优先关系
----------------------------------------------------------------
x1 \ x2| + | - | * | / | ( | ) | # |
----------------------------------------------------------------
+ | > | > | < | < | < | > | > |
----------------------------------------------------------------
- | > | > | < | < | < | > | > |
----------------------------------------------------------------
* | > | > | > | > | < | > | > |
----------------------------------------------------------------
/ | > | > | > | > | < | > | > |
----------------------------------------------------------------
( | > | > | > | > | > | = | |
----------------------------------------------------------------
) | > | > | > | > | | > | > |
----------------------------------------------------------------
# | < | < | < | < | < | | = |
----------------------------------------------------------------
*/
char ret[10][10]={
{'>','>','<','<','<','>','>'},{'>','>','<','<','<','>','>'},{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},{'<','<','<','<','<','=',' '},{'>','>','>','>',' ','>','>'},
{'<','<','<','<','<',' ','='}
};
void init(){
Map.insert(pair<char,int>('+',0));
Map.insert(pair<char,int>('-',1));
Map.insert(pair<char,int>('*',2));
Map.insert(pair<char,int>('/',3));
Map.insert(pair<char,int>('(',4));
Map.insert(pair<char,int>(')',5));
Map.insert(pair<char,int>('#',6));
}
int operate(char x,int a,int b){
if(x=='/'){
return a/b;
}
else if(x=='*'){
return a*b;
}
else if(x=='+'){
return a+b;
}
else return a-b;
}
int evaluateExpression(){
ch.push('#');
char c,p=' ';
c=getchar();
while(c!='#'||ch.top()!='#'){
if(c=='\n') c='#';//最后一个换行也会被读进来,变成'#'就行
if(c<='9'&&c>='0'){
int v;
if(p<='9'&&p>='0'){
v=num.top()*10+c-'0';
num.pop();
}
else v=c-'0';
num.push(v);
p=c;
c=getchar();
}
else{
switch(ret[Map[ch.top()]][Map[c]]){
case '<': ch.push(c); p=c; c=getchar(); break;
case '=': ch.pop(); p=c; c=getchar() ; break;
case '>': p=c;
char temp=ch.top(); ch.pop();
int b=num.top(); num.pop();
int a=num.top(); num.pop();
num.push(operate(temp,a,b));
break;
}
}
}
int x=num.top();
num.pop();
return x;
}
int main()
{
init(); ;
cout<<evaluateExpression();
return 0;
}