点击一下吧hh
栈是特殊的线性表,特点:先进后出~~
直接用STL很方便的,不过还是从底层重新学一遍吧。
如果你是为了找代码,应付老师的作业,建议右上角关掉窗口。
关于栈的一些操作
栈的顺序存储结构
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdlib>
#define ll long long
#define stack_maxsize 500
#define Selemtype int
#define Status int
#define False 0
#define OK 1
using namespace std;
typedef struct
{
Selemtype data[stack_maxsize];
int top;
}sq_stack;
//当存在第一个数据时,top=0,所以把空栈的top设为-1
Status init_stack(sq_stack &S)//待完善
{
S.top=-1;
return OK;
}
//销毁
//Status destory_stack(sq_stack &S);
//清空
Status clear_stack(sq_stack &S)
{
S.top=-1;
return OK;
}
//判断是否为空
Status empty_stack(sq_stack &S)
{
if(S.top==-1) return OK;
return False;
}
//栈的长度
Status length_stack(sq_stack S)
{
if(!empty_stack(S)) return S.top+1;
else return False;
}
//出栈
Status pop_stack(sq_stack &S,Selemtype *e)
{
if(S.top==-1) return False;
*e=S.data[S.top];
S.top--;
return OK;
}
//入栈
Status push_stack(sq_stack &S,Selemtype e)
{
if(S.top==stack_maxsize-1) return False;
S.top++;//栈顶指针加+
S.data[S.top]=e; //入栈
return OK;
}
//获得栈顶元素
Status top_stack(sq_stack S,Selemtype *e)
{
if(!empty_stack(S))
{
*e=S.data[S.top];
return OK;
}else return False;
}
//遍历
void traverse_stack(sq_stack S)
{
for(int i=0;i<=S.top;i++)
{
cout<<S.data[i]<<" ";
}
cout<<endl;
}
int main()
{
int n;
sq_stack S;
Selemtype e;
init_stack(S);
cout<<"input the number of pushing: ";
cin>>n;
//入栈
for(int i=0;i<n;i++)
{
int c=rand()%10+1;
push_stack(S,c);
}
//遍历
cout<<"low->top: ";
traverse_stack(S);
//长度
cout<<"the length of stack: ";
cout<<length_stack(S)<<endl;
//出栈
cout<<"pop: ";
pop_stack(S,&e);
cout<<e<<endl;
//入栈
cout<<"input number you want to push: ";
cin>>e;
push_stack(S,e);
//入栈之后的测试
cout<<"after pushing:";
cout<<"low->top: ";
traverse_stack(S);
cout<<"the length of stack: ";
cout<<length_stack(S)<<endl;
cout<<"the number of top: ";
top_stack(S,&e);
cout<<e<<endl;
cout<<"clear_stack…ing…"<<endl;
if(clear_stack(S))
{
cout<<"clear finished!!!!!"<<endl;
} else cout<<"error"<<endl;
return 0;
}
栈的链式存储结构
/*
malloc :
(返回指针类型)malloc(申请空间大小,一般是类型个数×sizeof(类型))
*/
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdlib>
#define ll long long
#define stack_size 100
#define stackincrement 10
#define Selemtype int
#define Status int
#define False 0
#define OK 1
using namespace std;
typedef struct
{
Selemtype *base;//在栈构造之前和毁灭之后 base 的值为 null
Selemtype *top;//栈顶指针(非空栈中的栈顶指针始终在栈顶元素的下一个位置)
int stacksize;//当前已经分配的存储空间
}sq_stack;
//!!!!!! base top 可是两个指针啊 !!!!!
//初始化
Status init_stack(sq_stack &S)
{
S.base=(Selemtype *)malloc(stack_size*sizeof(Selemtype));
if(!S.base) return False;
S.top=S.base;
S.stacksize=stack_size;
}
//销毁 栈 S
Status destory_stack(sq_stack &S)
{
//if(S.base)
//{
// S.base=NULL;
// return OK;
//}
S.top==S.base;
free(S.base);//注意!释放的不是指针,而是指针指向的空间内存~~~~
S.base=NULL;//然后指针指向空
S.top=NULL;
return OK;
}
//置为空栈
Status clear_stack(sq_stack &S)
{
S.top=S.base;
S.stacksize=0;
return OK;
}
//判断是否为空栈
Status empty_stack(sq_stack S)
{
if(S.base==S.top) return OK;
else return False;
}
//栈的长度
Status length_stack(sq_stack S)
{
if(S.base==NULL||S.base==S.top) return False;
else
return (S.top-S.base);
}
//pop 出栈
Status pop_stack(sq_stack &S,Selemtype &e)
{
if(empty_stack(S)) return False;
S.top--;
e=*(S.top);
return OK;
}
//push 入栈 e入栈
Status push_stack(sq_stack &S,Selemtype e)
{
if(S.top-S.base>=S.stacksize)//空间不够 要拓展空间
{
S.base=(Selemtype *)malloc((S.stacksize+stackincrement)*sizeof(Selemtype));
if(!S.base) return False;
S.top=S.base+S.stacksize;
S.stacksize+=stackincrement;
}
*S.top=e;
S.top++;
return OK;
}
//get.top 操作
Status get_top(sq_stack S,Selemtype &e)
{
if(empty_stack(S)) return False;
e=*(S.top-1);
return OK;
}
//从栈底到栈顶依次 输出每个元素
void traverse_stack(sq_stack S)
{
if(empty_stack(S)) cout<<"Error"<<endl;
else
{
while(S.top!=S.base)
{
cout<<*(S.top-1)<<" ";
S.top--;
}
cout<<endl;
}
}
int main()
{
int e;
sq_stack S;
if(init_stack(S))
{
cout<<"Initialization is completed!"<<endl;
}else {
cout<<"Error"<<endl;
return 0;
}
//入栈:
for(int i=1;i<=10;i++)
{
push_stack(S,i*2);
}
//长度
cout<<"The length of stack: "<<length_stack(S)<<endl;
//得到栈顶元素
if(get_top(S,e))
{
cout<<"The top of element: "<<e<<endl;
}else cout<<"Error"<<endl;
//出栈
//cout<<"out: "<<endl;
//while(pop_stack(S,e))
//{
// cout<<e<<" ";
//}
//cout<<endl;
//遍历栈里面的元素:
cout<<"traverse: ";
traverse_stack(S);
//再次得到栈顶元素 (从这点可以知道,traverse_stack 并没有对栈中元素 做出栈 操作,只是指针在动,数据并没有消失)
if(get_top(S,e))
{
cout<<"The top of element: "<<e<<endl;
} else cout<<"Error"<<endl;
//入栈
//cout<<"Input an element you want to insert: ";
int flag=1;
while(flag)
{
cout<<"Input an element you want to insert: ";
char c;
cin>>e;
push_stack(S,e);
traverse_stack(S);
cout<<"continue pushing??? (Y or N)"<<endl;
cin>>c;
if(c=='Y'||c=='y') flag=1;
else flag=0;
}
//出栈
int flag1=1;
cout<<"out: ";
while(flag1)
{
char c;
if(pop_stack(S,e))
{
cout<<e<<endl<<endl;
}
cout<<"continue outing??? (Y or N)"<<endl;
cin>>c;
if(c=='Y'||c=='y') flag1=1;
else flag1=0;
}
//清空
if(clear_stack(S))
{
//traverse_stack(S);
// 判断是否为空
if(empty_stack(S))
cout<<"Emptying is done!"<<endl;
else cout<<"error"<<endl;
}else cout<<"error"<<endl;
//销毁
if(destory_stack(S))
{
cout<<"destory finished!"<<endl;
}
return 0;
}
栈的应用举例: 进制转换
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdlib>
#define ll long long
#define stack_size 100
#define stackincrement 10
#define Selemtype int
#define Status int
#define False 0
#define OK 1
using namespace std;
typedef struct
{
Selemtype *base;//在栈构造之前和毁灭之后 base 的值为 null
Selemtype *top;//栈顶指针(非空栈中的栈顶指针始终在栈顶元素的下一个位置)
int stacksize;//当前已经分配的存储空间
}sq_stack;
//!!!!!! base top 可是两个指针啊 !!!!!
//初始化
Status init_stack(sq_stack &S)
{
S.base=(Selemtype *)malloc(stack_size*sizeof(Selemtype));
if(!S.base) return False;
S.top=S.base;
S.stacksize=stack_size;
}
//销毁 栈 S
Status destory_stack(sq_stack &S)
{
//if(S.base)
//{
// S.base=NULL;
// return OK;
//}
S.top==S.base;
free(S.base);//注意!释放的不是指针,而是指针指向的空间内存~~~~
S.base=NULL;//然后指针指向空
S.top=NULL;
return OK;
}
//置为空栈
Status clear_stack(sq_stack &S)
{
S.top=S.base;
S.stacksize=0;
return OK;
}
//判断是否为空栈
Status empty_stack(sq_stack S)
{
if(S.base==S.top) return OK;
else return False;
}
//栈的长度
Status length_stack(sq_stack S)
{
if(S.base==NULL||S.base==S.top) return False;
else
return (S.top-S.base);
}
//pop 出栈
Status pop_stack(sq_stack &S,Selemtype &e)
{
if(empty_stack(S)) return False;
S.top--;
e=*(S.top);
return OK;
}
//push 入栈 e入栈
Status push_stack(sq_stack &S,Selemtype e)
{
if(S.top-S.base>=S.stacksize)//空间不够 要拓展空间
{
S.base=(Selemtype *)malloc((S.stacksize+stackincrement)*sizeof(Selemtype));
if(!S.base) return False;
S.top=S.base+S.stacksize;
S.stacksize+=stackincrement;
}
*S.top=e;
S.top++;
return OK;
}
//get.top 操作
Status get_top(sq_stack S,Selemtype &e)
{
if(empty_stack(S)) return False;
e=*(S.top-1);
return OK;
}
//从栈底到栈顶依次 输出每个元素
void traverse_stack(sq_stack S)
{
if(empty_stack(S)) cout<<"Error"<<endl;
else
{
while(S.top!=S.base)
{
cout<<*(S.top-1)<<" ";
S.top--;
}
cout<<endl;
}
}
//2 8 16
int main()
{
int n,k,e;
sq_stack S;
init_stack(S);
cout<<"input number you want to converse:";
cin>>n;
cout<<"Hexadecimal number(2,8,16):";
cin>>k;
if(k!=2&&k!=8&&k!=16)
{
cout<<"error"<<endl;
return 0;
}
/*
关于16进制
10:A 11:B 12:C 13:D 14:E 15:F
*/
while(n)
{
int c=n%k;
push_stack(S,c);
n/=k;
}
while(!empty_stack(S))
{
pop_stack(S,e);
if(e>=10) cout<<char(e-10+'A');
else cout<<e;
}
return 0;
}
/*
int main()
{
int e;
sq_stack S;
if(init_stack(S))
{
cout<<"Initialization is completed!"<<endl;
}else {
cout<<"Error"<<endl;
return 0;
}
//入栈:
for(int i=1;i<=10;i++)
{
push_stack(S,i*2);
}
//长度
cout<<"The length of stack: "<<length_stack(S)<<endl;
//得到栈顶元素
if(get_top(S,e))
{
cout<<"The top of element: "<<e<<endl;
}else cout<<"Error"<<endl;
//出栈
//cout<<"out: "<<endl;
//while(pop_stack(S,e))
//{
// cout<<e<<" ";
//}
//cout<<endl;
//遍历栈里面的元素:
cout<<"traverse: ";
traverse_stack(S);
//再次得到栈顶元素 (从这点可以知道,traverse_stack 并没有对栈中元素 做出栈 操作,只是指针在动,数据并没有消失)
if(get_top(S,e))
{
cout<<"The top of element: "<<e<<endl;
} else cout<<"Error"<<endl;
//入栈
//cout<<"Input an element you want to insert: ";
int flag=1;
while(flag)
{
cout<<"Input an element you want to insert: ";
char c;
cin>>e;
push_stack(S,e);
traverse_stack(S);
cout<<"continue pushing??? (Y or N)"<<endl;
cin>>c;
if(c=='Y'||c=='y') flag=1;
else flag=0;
}
//出栈
int flag1=1;
cout<<"out: ";
while(flag1)
{
char c;
if(pop_stack(S,e))
{
cout<<e<<endl<<endl;
}
cout<<"continue outing??? (Y or N)"<<endl;
cin>>c;
if(c=='Y'||c=='y') flag1=1;
else flag1=0;
}
//清空
if(clear_stack(S))
{
//traverse_stack(S);
// 判断是否为空
if(empty_stack(S))
cout<<"Emptying is done!"<<endl;
else cout<<"error"<<endl;
}else cout<<"error"<<endl;
//销毁
if(destory_stack(S))
{
cout<<"destory finished!"<<endl;
}
return 0;
} */
栈的应用举例:括号匹配(超经典的~~)
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdlib>
#define ll long long
#define stack_size 100
#define stackincrement 10
#define Selemtype char
#define Status int
#define False 0
#define OK 1
using namespace std;
typedef struct
{
Selemtype *base;//在栈构造之前和毁灭之后 base 的值为 null
Selemtype *top;//栈顶指针(非空栈中的栈顶指针始终在栈顶元素的下一个位置)
int stacksize;//当前已经分配的存储空间
}sq_stack;
//!!!!!! base top 可是两个指针啊 !!!!!
//初始化
Status init_stack(sq_stack &S)
{
S.base=(Selemtype *)malloc(stack_size*sizeof(Selemtype));
if(!S.base) return False;
S.top=S.base;
S.stacksize=stack_size;
}
//销毁 栈 S
Status destory_stack(sq_stack &S)
{
//if(S.base)
//{
// S.base=NULL;
// return OK;
//}
S.top==S.base;
free(S.base);//注意!释放的不是指针,而是指针指向的空间内存~~~~
S.base=NULL;//然后指针指向空
S.top=NULL;
return OK;
}
//置为空栈
Status clear_stack(sq_stack &S)
{
S.top=S.base;
S.stacksize=0;
return OK;
}
//判断是否为空栈
Status empty_stack(sq_stack S)
{
if(S.base==S.top) return OK;
else return False;
}
//栈的长度
Status length_stack(sq_stack S)
{
if(S.base==NULL||S.base==S.top) return False;
else
return (S.top-S.base);
}
//pop 出栈
Status pop_stack(sq_stack &S,Selemtype &e)
{
if(empty_stack(S)) return False;
S.top--;
e=*(S.top);
return OK;
}
//push 入栈 e入栈
Status push_stack(sq_stack &S,Selemtype e)
{
if(S.top-S.base>=S.stacksize)//空间不够 要拓展空间
{
S.base=(Selemtype *)malloc((S.stacksize+stackincrement)*sizeof(Selemtype));
if(!S.base) return False;
S.top=S.base+S.stacksize;
S.stacksize+=stackincrement;
}
*S.top=e;
S.top++;
return OK;
}
//get.top 操作
Status get_top(sq_stack S,Selemtype &e)
{
if(empty_stack(S)) return False;
e=*(S.top-1);
return OK;
}
//从栈底到栈顶依次 输出每个元素
void traverse_stack(sq_stack S)
{
if(empty_stack(S)) cout<<"Error"<<endl;
else
{
while(S.top!=S.base)
{
cout<<*(S.top-1)<<" ";
S.top--;
}
cout<<endl;
}
}
int main()
{
/*输入一堆括号(“[] () 两种”),判断是否匹配 如果匹配的话 最后判断 栈是不是空 如果是 输出yes 否则 no*/
/*括号匹配思路:
如果是[ ( 这种的话直接进栈,如果是 ) ] 的话 与 栈顶元素 看是否匹配
如果是的话 栈顶元素出栈 否则 与之匹配的 括号也要进栈 */
sq_stack S;
init_stack(S);
char s[100]={0},e;
int len;
cin>>s;//输入括号
len=strlen(s);//括号的长度
if(len%2)//如果是奇数的话肯定就不能匹配了~~~
{
cout<<"NO"<<endl;
return 0;
}
//循环进栈出栈
for(int i=0;i<len;i++)
{
if(s[i]=='('||s[i]=='[')
{
push_stack(S,s[i]);
continue;
}
if(s[i]==']')
{
if(get_top(S,e))//如果栈顶元素存在的话,就进行匹配 不然入栈
{
if(e=='[')
{
pop_stack(S,e);//匹配了 可以出栈了~~~~
}else push_stack(S,s[i]);
}else push_stack(S,s[i]);
}
if(s[i]==')')
{
if(get_top(S,e))//同理
{
if(e=='(')
{
pop_stack(S,e);//匹配了 可以出栈了~~~~
}else push_stack(S,s[i]);
}else push_stack(S,s[i]);
}
}
if(empty_stack(S))
{
cout<<"YES"<<endl;
}else cout<<"NO"<<endl;
return 0;
}
栈的应用举例:表达式求值
注意:计算的数字不能是两位数以上的,而且表达式输入以后要以‘#’结尾 ,可以看出此代码还是很有局限性的。。。。。哎~~~
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdlib>
#define ll long long
#define stack_size 100
#define stackincrement 10
#define Selemtype char
#define Status int
#define False 0
#define OK 1
using namespace std;
typedef struct
{
Selemtype *base;//在栈构造之前和毁灭之后 base 的值为 null
Selemtype *top;//栈顶指针(非空栈中的栈顶指针始终在栈顶元素的下一个位置)
int stacksize;//当前已经分配的存储空间
}sq_stack;
//!!!!!! base top 可是两个指针啊 !!!!!
//初始化
Status init_stack(sq_stack &S)
{
S.base=(Selemtype *)malloc(stack_size*sizeof(Selemtype));
if(!S.base) return False;
S.top=S.base;
S.stacksize=stack_size;
}
//销毁 栈 S
Status destory_stack(sq_stack &S)
{
//if(S.base)
//{
// S.base=NULL;
// return OK;
//}
S.top==S.base;
free(S.base);//注意!释放的不是指针,而是指针指向的空间内存~~~~
S.base=NULL;//然后指针指向空
S.top=NULL;
return OK;
}
//置为空栈
Status clear_stack(sq_stack &S)
{
S.top=S.base;
S.stacksize=0;
return OK;
}
//判断是否为空栈
Status empty_stack(sq_stack S)
{
if(S.base==S.top) return OK;
else return False;
}
//栈的长度
Status length_stack(sq_stack S)
{
if(S.base==NULL||S.base==S.top) return False;
else
return (S.top-S.base);
}
//pop 出栈
Status pop_stack(sq_stack &S,Selemtype &e)
{
if(empty_stack(S)) return False;
S.top--;
e=*(S.top);
return OK;
}
//push 入栈 e入栈
Status push_stack(sq_stack &S,Selemtype e)
{
if(S.top-S.base>=S.stacksize)//空间不够 要拓展空间
{
S.base=(Selemtype *)malloc((S.stacksize+stackincrement)*sizeof(Selemtype));
if(!S.base) return False;
S.top=S.base+S.stacksize;
S.stacksize+=stackincrement;
}
*S.top=e;
S.top++;
return OK;
}
//get.top 操作
Selemtype get_top(sq_stack S)
{
if(empty_stack(S)) return False;
return (*(S.top-1));
}
//从栈底到栈顶依次 输出每个元素
void traverse_stack(sq_stack S)
{
if(empty_stack(S)) cout<<"Error"<<endl;
else
{
while(S.top!=S.base)
{
cout<<*(S.top-1)<<" ";
S.top--;
}
cout<<endl;
}
}
int in(Selemtype c)
{
switch(c)
{
case'+':
case'-':
case'*':
case'/':
case'(':
case')':
case'#':return 1;
default:return 0;
}
}
//运算
char operate_stack(int a,char op,int b)
{
switch(op)
{
case '+': return (char)(a+b+'0');
case '-': return (char)(a-b+'0');
case '*': return (char)(a*b+'0');
case '/': return (char)(a/b+'0');
default: return '0';
}
}
//运算符比较
int compare_stack(char op1,char op2)//大的返回 3 小的 返回 2 等于 返回 1 错误 返回 0
{
if(op1=='+')
{
if((op2=='+')||(op2=='-')||(op2==')')||(op2=='#'))
return 3;
else return 2;
}
else if(op1=='-')
{
if((op2=='+')||(op2=='-')||(op2==')')||(op2=='#'))
{
return 3;
}else return 2;
}
else if(op1=='*')
{
if(op2=='(')
return 2;
else return 3;
}
else if(op1=='/')
{
if(op2=='(')
return 2;
else return 3;
}
else if(op1=='(')
{
if(op2==')')
return 1;
else if((op2=='+')||(op2=='-')||(op2=='*')||(op2=='/')||(op2=='('))
return 2;
}
else if(op1==')')
{
if(op2!='(')
return 3;
}
else if(op1=='#')
{
if(op2=='#')
return 1;
else if((op2=='+')||(op2=='-')||(op2=='*')||(op2=='/')||(op2=='('))
return 2;
}
return 0;
}
//运算符比较相等的话 入栈
int main()
{
//如果是数字就入栈 如果是运算符 就跟 栈顶元素 作比较 如果高的话就进栈,否则运算
sq_stack S_optr,S_opnd;//两个栈 一个是运算符栈一个是运算数栈 char类型
char c;
Selemtype e,a,b;
init_stack(S_optr);
init_stack(S_opnd);
push_stack(S_optr,'#'); //最低级的#入运算符栈
cout<<"input ( End with '#' ): ";
c=getchar();//注意一个字符一个字符的输入;
int cnt=0;
while(c!='#'||get_top(S_optr)!='#')
{
if(c>='0'&&c<='9') {
push_stack(S_opnd,c);
c=getchar();//不要忘了 继续下一个字符的输入,结束按回车
}
else
{//新输入的字符与 运算符栈顶 元素 比较 优先级, 高的 入栈 低的 栈顶元素出栈,进行运算
if(!in(c))//判断是不是合法字符
{
cout<<"error"<<endl;
return 0;
}
int op=compare_stack(get_top(S_optr),c);
// cout<<op<<endl;
switch(op)
{
case 2: //栈顶元素低,字符进栈, 2 <---> '<'
push_stack(S_optr,c);
// cout<<"case 2:optr ";traverse_stack(S_optr);
// cout<<"case 2:opnd ";traverse_stack(S_opnd);
c=getchar();//继续输入
break;
case 1://栈顶元素相等 1 <---> '='
pop_stack(S_optr,e);// 运算符规则里,()相等 所以脱括号 出栈
// cout<<"case 1 optr "; traverse_stack(S_optr);
// cout<<"case 1 opnd ";traverse_stack(S_opnd);
c=getchar();
break;
case 3://栈顶元素优先级高,出栈, 运算数 出栈两个哦 3 <--> '='
pop_stack(S_optr,e);
pop_stack(S_opnd,b);
pop_stack(S_opnd,a);//b比a先出
push_stack(S_opnd,operate_stack((int)a-'0',e,(int)b-'0'));
break;
}
}
}
// traverse_stack(S_opnd);
// traverse_stack(S_optr);
char ans=get_top(S_opnd);
if(ans>='0'&&ans<='9')
cout<<ans<<endl;
else cout<<int(ans-'0')<<endl;
return 0;
}