来吧,开始
还是和之前一样,先看一下链栈的图形长什么样吧
1.存储结构
链栈的存储结构和单链表的类似,都是有一个数据域data,一个指针域next。
typedef struct StackNode
{
SElemType data;
struct StackNode *next;
}StackNode,*LinkStack;
2.初始化
思路:将链栈置为空。
void InitStack(LinkStack &S)
{
S=NULL;
}
3.判空
思路:直接返回bool类型 S=NULL;
bool StackEmpty(LinkStack &S)
{
return S==NULL;
}
4.长度
思路:生成一个指针p先指向首元结点,以及一个计数的。当p不为空时,p一直往下移。计数++;
int StackEmpty(LinkStack S)
{
LinkStack p;
p=S;
int count=0;
while(p)
{
count++;
p=p->next;
}
cout<<count<<endl;
}
5.入栈
思路:栈的特点就是:从栈顶进。所以生成一个新节点p,p的数据域赋值为e,p的指针域指向S。S=p;S永远是栈顶结点。
void Push(LinkStack &S,SElemType e)
{
LinkStack p=new StackNode;
p->data=e;
p->next=S;
S=p;
}
6.出栈
思路:生成一个新节点p来保存被删除的结点。先判断栈是否为空。不为空时将S->data赋值给e,p=S;S往下走,删除p结点。
Status Pop(LinkStack &S,SElemType e)
{
LinkStack p=new StackNode;
if(S==NULL)
return ERROR;
e=S->data;
p=S;
S=S->next;
delete p;
}
7.取栈顶元素
思路:先判断栈是否为空。不为空时,e=S->data;S=S->data;
Status GetTop(LinkStack S,SElemType &e)
{
if(S==NULL)
return ERROR;
e=S->data;
S=S->next;
return e;
}
8.显示链栈
思路:生成一个结点p指向栈顶,当p不为空时,输出p的数据域,p往下移。
void DisplayStack(LinkStack S)
{
LinkStack p=S;
while(p)
{
cout<<p->data<<endl;
p=p->next;
}
cout<<endl;
}
9.清空
思路:将S置为空即可
void ClearStack(LinkStack &S)
{
S=NULL;
}
10.销毁
思路:生成一个指针p=S; 当p不为空时,S往下移一个,删除p即可。
void DestoryStack(LinkStack &S)
{
LinkStack p=S;
while(p)
{
S=S->next;
delete p;
}
}
完整代码:
#include<iostream>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
typedef int SElemType;
typedef int Status;
typedef struct StackNode
{
SElemType data;
struct StackNode *next;
}StackNode,*LinkStack;
void InitStack(LinkStack &S)//S在这里是节点的意思
{
S=NULL;
}
bool StackEmpty(LinkStack S)
{
return (S==NULL);
}
int StackLength(LinkStack S)
{
LinkStack p;
p=S;
int count=0;
while(p)
{
count++;
p=p->next;
}
cout<<count<<endl;
return OK;
}
void Push(LinkStack &S,SElemType e)
{
LinkStack p=new StackNode;
p->data=e;
p->next=S;
S=p; //S永远是栈顶节点
}
Status Pop(LinkStack &S,SElemType &e)
{
LinkStack p=new StackNode;
//先判断栈是否为空
if(S==NULL)
return ERROR;
e=S->data;
p=S;
S=S->next;
delete p;
return OK;
}
Status GetTop(LinkStack S,SElemType &e)
{
//先判断站是否空
if(S==NULL)
return ERROR;
e=S->data;
S=S->next;
return e;
}
void DispalyStack(LinkStack S)
{
LinkStack p;
p=S;
while(p)
{
cout<<p->data<<endl;
p=p->next;
}
cout<<endl;
}
void ClearStack(LinkStack &S)
{
S=NULL;
}
void DestoryStack(LinkStack &S)
{
LinkStack p=new StackNode;
p=S;
while(p)
{
S=S->next;
delete p;
}
}
void show_help()
{
cout<<"1----清空顺序栈"<<endl;
cout<<"2----判断顺序栈是否为空"<<endl;
cout<<"3----求顺序栈长度"<<endl;
cout<<"4----入栈"<<endl;
cout<<"5----出栈"<<endl;
cout<<"6----求栈顶元素"<<endl;
cout<<"7----显示顺序栈"<<endl;
cout<<" 退出,输出一个负数!"<<endl;
}
int main()
{
int operate_code;
show_help();
//定义线性表变量,如SqList L;
LinkStack S;
InitStack(S);
while(1)
{
cout<<"请输入操作代码:";
cin>>operate_code;
if(operate_code==1)
{
ClearStack(S);
}
else if(operate_code==2)
{
if(!StackEmpty(S))
cout<<"The LinkList is not Empty"<<endl;
else
cout<<"The LinkList is Empty"<<endl;
}
else if(operate_code==3)
{
StackLength(S);
}
else if(operate_code==4)
{
SElemType e;
cin>>e;
Push(S,e);
}
else if(operate_code==5)
{
SElemType e;
if(Pop(S,e))
cout<<"栈顶元素"<<e<<"出栈成功"<<endl;
else
cout<<"栈为空"<<endl;
}
else if(operate_code==6)
{
SElemType e;
if(GetTop(S,e))
cout<<"栈顶元素为:"<<e<<endl;
else
cout<<"空栈,无栈顶元素!"<<endl;
}
else if(operate_code==7)
{
DispalyStack(S);
}
else if(operate_code<0)
{
break;
}
else
{
cout<<"\n操作码错误!!!"<<endl;
cin.clear();
cin.sync();
show_help();
}
}
//调用销毁线性表函数,如 Destroy_List(L);
DestoryStack(S);
return 0;
}
emm...链栈比单链表简单点,插入删除的时候只考虑栈顶即可,所以还是很容易理解和实现的。