链栈的实现思路同顺序栈类似,顺序栈是将数顺序表(数组)的一端作为栈底,另一端为栈顶;链栈也如此,通常我们将链表的头部作为栈顶,尾部作为栈底。
将链表头部作为栈顶的一端,可以避免在实现数据 "入栈" 和 "出栈" 操作时做大量遍历链表的耗时操作。
链表的头部作为栈顶,意味着:
- 在实现数据"入栈"操作时,需要将数据从链表的头部插入;
- 在实现数据"出栈"操作时,需要删除链表头部的首元节点
因此,链栈实际上就是一个只能采用头插法插入或删除数据的链表。
代码如下:
#include "stdio.h"
#include "stdlib.h"
typedef struct linestack{ //定义链式栈结构
int data;
struct linestack *next;
}linestack; //用typedef将 struct linestack取代为linestack
linestack *push(linestack *stack,int a) //入栈操作
{
linestack *line=(linestack*)malloc(sizeof(linestack)); //新建栈分配动态内存
line->data=a; //将数据域带入
line->next=stack; //将新的栈顶节点指向老节点
stack=line; //新栈顶为line
return stack; //返回栈顶
}
linestack *pop(linestack *stack) //出栈操作
{
if(stack) //如果栈顶不为空
{
linestack *p=stack; //定义个指针节点代表栈顶
printf("弹栈元素为%d\t",p->data); //输出栈顶元素
stack=p->next; //将下个节点作为新栈顶
free(p); //释放掉p节点 老栈顶
if(stack) //如果新栈顶存在
{
printf("新栈顶为%d\n",stack->data); //输出新栈顶的元素
}
else{
printf("栈已空\n"); //否则输出栈空
}
}
else{
printf("栈内没有元素\n"); //当一开始栈就没有元素时输出空栈
return stack;
}
return stack;
}
int main()
{
linestack *stack=NULL; //定义栈顶为空
stack=push(stack,1); //入栈操作
stack=push(stack,2);
stack=push(stack,3);
stack=push(stack,4);
stack=pop(stack); //出栈操作
stack=pop(stack);
stack=pop(stack);
stack=pop(stack);
stack=pop(stack);
return 0;
}
运行结果: