目录
一.栈的定义和特点
1.栈的定义
栈也是线性表,其特殊性在于栈的基本操作是线性表的操作的子集,即栈是限定仅在表尾进行插入和删除操作的线性表。(一种操作受限的线性表)
2.栈的特点
栈是按先进后出的原则进行修改的,这是栈最大的特点。
二.栈的表示和实现
1.顺序栈的表示和实现
1.1 栈的表示
栈只能在栈顶操作,因此对栈操作时不允许修改栈底指针,只能修改栈顶指针。
typedef struct{
ElemType *base;//栈底指针
ElemType *top;//栈顶指针
int stacksize;//栈的最大容量
}SqStack;
1.2初始化栈
int InitStack(SqStack &S){
S.base=new ElemType[MAXSIZE];//为S.base分配MAXSIZE*sizeof(ElemType)个字节的空间
if(!S.base) exit(OVERFLOW);//分配不成功则退出
S.top=S.base;
S.stacksize=MAXSIZE;
return OK;
}
1.3进栈![](https://img-blog.csdnimg.cn/51a9945ca97646619bd7ed42bbdebaf4.png)
e进栈后,栈顶指针并不是指向e的,而是e的下一个地址。
int Push(SqStack &S,ElemType e)
{
if(S.top-S.base==S.stacksize) return ERROR; //栈满
*S.top=e;//将e赋给S.Top
S.top++;//栈顶指针加1
return OK;
}
1.4 出栈
e出栈后,e的值在栈中实际上并没有删除,但我们认为栈已出栈,栈顶指针指向e,此时栈顶元素为栈顶指针的前一个地址。
int Pop(SqStack &S,ElemType &e)
{
if(S.base==S.top)
{
cout<<"栈空"<<endl;
return ERROR;//栈空
}
S.top--;//栈顶指针减1
e=*S.top;//将弹出元素保存到e中
return OK;
}
1.5判断栈是否为空
int IsEmpty(SqStack S)
{
if(S.base==S.top) return 1;
else return 0;
}
1.6取栈顶元素
ElemType GetTop(SqStack S)
{
if(S.base==S.top)
cout<<"栈空"<<endl;
else return *(S.top-1);//此时不时S.top--,因为取栈顶元素不需要修改栈顶指针
}
1.7遍历栈中元素
void TraverseStack(SqStack S){
if(S.base==S.top){
cout<<"栈空";
return;
}
cout<<"栈的遍历结果为:"<<"\n";
while(S.base!=S.top){
S.top--;
cout<<*S.top<<"\n";
}
}
1.8完整代码
#include<iostream>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR -1
#define OVERFLOW 0
#define ElemType int
typedef struct{
ElemType *base;
ElemType *top;
int stacksize;
}SqStack;
int InitStack(SqStack &S);//初始化栈
int Push(SqStack &S,ElemType e);//将元素e压进栈
int Pop(SqStack &S,ElemType &e);//栈顶元素出栈,并将出栈元素保存在e中
int IsEmpty(SqStack S);//判断栈是否为空
ElemType GetTop(SqStack S);//取栈顶元素
void TraverseStack(SqStack S);//遍历栈中元素
int main()
{
int n;
ElemType e;
SqStack S;
InitStack(S);
cout<<"请输入压进栈的元素个数:";
cin>>n;
cout<<"请输入元素:"<<"\n";
while(n--){
cin>>e;
Push(S,e);
}
TraverseStack(S);
return 0;
}
int InitStack(SqStack &S){
S.base=new ElemType[MAXSIZE];
if(!S.base) exit(OVERFLOW);
S.top=S.base;
S.stacksize=MAXSIZE;
return OK;
}
int Push(SqStack &S,ElemType e)
{
if(S.top-S.base==S.stacksize) return ERROR; //栈满
*S.top=e;
S.top++;
return OK;
}
int Pop(SqStack &S,ElemType &e)
{
if(S.base==S.top)
{
cout<<"栈空"<<endl;
return ERROR;//栈空
}
S.top--;
e=*S.top;
return OK;
}
int IsEmpty(SqStack S)
{
if(S.base==S.top) return 1;
else return 0;
}
ElemType GetTop(SqStack S)
{
if(S.base==S.top)
cout<<"栈空"<<endl;
else return *(S.top-1);
}
void TraverseStack(SqStack S){
if(S.base==S.top){
cout<<"栈空";
return;
}
cout<<"栈的遍历结果为:"<<"\n";
while(S.base!=S.top){
S.top--;
cout<<*S.top<<"\n";
}
}
2.链栈的表示和实现
链栈的操作和链表的操作几乎相同。
2.1链栈的表示
typedef struct LNode{
ElemType data;//数据域
struct LNode* next;//指针域
}LNode,*LinkStack;
2.2初始化链栈
链栈不需要考虑栈满的问题,也不用提前分配空间,因此初始化时只需将S置为空即可。
int InitStack(LinkStack &S){
S==NULL;
return OK;
}
2.3进栈
int Push(LinkStack &S,ElemType e){
LNode* p=new LNode;
p->data=e;
p->next=S;
S=p;
return OK;
}
2.4出栈
int Pop(LinkStack &S,ElemType &e){
if(!S) return ERROR;//栈空
LNode* p=new LNode;
p=S;
e=p->data;
S=p->next;
delete p;
return OK;
}
2.5取栈顶元素
ElemType GetTop(LinkStack S){
if(S)
return S->data;
}
2.6遍历栈中元素
void Traverse(LinkStack S){
if(!S){
cout<<"栈空";
return;
}
cout<<"栈的遍历结果为:";
LNode *p=S;
while(p){
cout<<p->data<<" ";
p=p->next;
}
cout<<"\n";
}
2.7完整代码
#include<iostream>
using namespace std;
#define ElemType int
#define OK 1
#define ERROR -1
typedef struct LNode{
ElemType data;
struct LNode* next;
}LNode,*LinkStack;
int InitStack(LinkStack &S);
int Push(LinkStack &S,ElemType e);
int Pop(LinkStack &S,ElemType &e);
ElemType GetTop(LinkStack S);
void Traverse(LinkStack S);
int main(){
int n;
ElemType e;
LinkStack S;
InitStack(S);
cout<<"请输入压进栈的元素个数:";
cin>>n;
cout<<"请输入元素:";
while(n--){
cin>>e;
Push(S,e);
}
Traverse(S);
return 0;
}
int InitStack(LinkStack &S){
S==NULL;
return OK;
}
int Push(LinkStack &S,ElemType e){
LNode* p=new LNode;
p->data=e;
p->next=S;
S=p;
return OK;
}
int Pop(LinkStack &S,ElemType &e){
if(!S) return ERROR;
LNode* p=new LNode;
p=S;
e=p->data;
S=p->next;
delete p;
return OK;
}
ElemType GetTop(LinkStack S){
if(S)
return S->data;
}
void Traverse(LinkStack S){
if(!S){
cout<<"栈空";
return;
}
cout<<"栈的遍历结果为:";
LNode *p=S;
while(p){
cout<<p->data<<" ";
p=p->next;
}
cout<<"\n";
}