链栈顾名思义,采用链表实现,其优点是不存在栈满上溢出的情况,其操作都是在头结点之后进行的,入栈类似与头插法建立链表。
注意头结点与栈顶节点的区别,在没有元素入栈时,栈仅有初始化的一个头结点,判断其是否为空只需判断s->next是否为NULL。
下面用C语言代码实现了链栈的基本操作:
运行环境:VS2017
运行示例:
代码:
#include<stdio.h>
#include<Windows.h>//防止程序一闪而过
#include<malloc.h>
typedef struct Node {//建立节点
int data;//数据域
struct Node *next;//指针域
}LinkStack;
/*建立空栈*/
void InitStack(LinkStack *&S)//*&为引用,可以直接修改实参指向的位置
{//链栈不带头结点,初始化链栈只需要把栈顶置为空
S = (LinkStack *)malloc(sizeof(LinkStack));
S->next = NULL;//栈为空的标志
}
/*判空操作*/
int Empty(LinkStack *S)
{
return (S->next == NULL);
}
/*销毁栈*/
void DestroyStack(LinkStack *&S)
{
Node *p = S;
while (S != NULL)
{
S = S->next;
free(p);
p = S;
}
}
/*入栈*/
void Push(LinkStack* &S, int x)//S为头结点
{
LinkStack *p;
p = (LinkStack *)malloc(sizeof(LinkStack));//创造一个工作节点
p->data = x;//存入要入栈的信息
p->next = S->next;
S->next = p;
}
/*出栈*/
int Pop(LinkStack *&S, int &ptr)//通过*ptr返回出栈的值,S为头结点
{
LinkStack *p=S->next;
if (S->next == NULL)
{
printf("堆栈为空。\n");
return 0;
}
else
{
ptr = p->data;//返回栈顶的值
S->next = p->next;//栈顶位置变化
free(p);//释放栈顶空间
return 1;
}
}
/*取栈顶元素*/
int GetTop(LinkStack *S,int &ptr)//与出栈差距在于不改变栈
{
if (S->next == NULL)
{
printf("堆栈为空get。\n");
return 0;
}
ptr = S->next->data;
return 1;
}
int main()
{
int x;//用来读取出栈数据
int y;
LinkStack *top;//定义栈顶指针并初始化
InitStack(top);
printf("对10,20进行入栈操作:\n");
Push(top, 10);
Push(top, 20);
if (GetTop(top, x) == 1)//如果取栈顶元素成功
{
printf("取栈顶元素操作:%d\n", x);
}
if (Pop(top,y) == 1)
{
printf("执行一次出栈操作,出栈的元素为%d\n",y);
}
if (Pop(top, y) == 1)
{
printf("执行一次出栈操作,出栈的元素为%d\n", y);
}
if (Pop(top, y) == 1)
{
printf("执行一次出栈操作,出栈的元素为%d\n", y);
}
system("pause");
return 0;
}