持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
1、结构体定义
栈可以视为一个特殊功能的链表,因为栈的主要的操作是对栈顶进行插入、删除,显然以链表的头部作为栈顶更为方便,所以也就不再需要头节点,同时为了方便操作和强调栈顶是栈的一个属性,可以这样定义:
//该部分与单链表结构体相同
typedef struct node
{
int data;
struct node *next;
}StackNode, *PStackNode;
//top始终指向最后一个入站的元素
typedef struct {
PStackNode top;
}LinkStack, *PLinkStack;
2、初始化栈
PLinkStack Init_LinkStack()
{
PLinkStack S;
S = (PLinkStack)malloc(sizeof(LinkStack));
if (S) S->top = NULL;
return (S);
}
3、判栈空
提高程序的健壮性,许多地方都需要判断栈是否为空,可以单独为此写一个函数。
int Empty_LinkStack(PLinkStack S)
{
return (S->top == NULL);
}
4、入栈
int Push_LinkStack(PLinkStack S, StackNode x)//S:栈名,x:节点
{
PStackNode p;
p = (PStackNode)malloc(sizeof(StackNode));
if (!p)
{
printf("内存溢出!");
}
//一节一节的加
p->data = x->data;
p->next = S->top;
S->top = p;
return 1;
}
5、出栈
int Pop_LinkStack(PLinkStack S, StackNode *x)
{
PStackNode p;
if (Empty_LinkStack(S))
{
printf("栈空,不能出栈!");
return 0;
}
*x->data= S->top->data;//可有可无
//取完之后,top向下移,由指向"n"改为指向"n-1"。
p = S->top;
S->top = S->top->next;
free(p);
return 1;
}
6、取栈顶元素
int GetTop_LinkStack(PLinkStack S, StackNode *x)
{
if (Empty_LinkStack(S)) {
printf("栈空,不能出栈!");
return 0;
}
x->data = S->top->data;
return 1;
}
7、栈销毁
void Destroy_LinkStack(PLinkStack *LS)
{//如果不手动销毁,该栈只有在程序结束之被系统自动销毁
PStackNode p, q;
if (*LS) {
p = (*LS)->top;
while (p)
{
q = p;
p = p->next;
free(q);
}
free(*LS);
}
*LS = NULL;
return;
}
8、遍历栈
栈具有先进后出的特点,所以在遍历栈时,也是先打印后进的元素
void Print_LinkStack(PLinkStack S)
{
PStackNode head = S->top;
while (head != NULL)
{
printf("%d\n", head->data);
head = head->next;
}
}
9、运行测试
1 2 3 4 5 6 7 8 9 0
栈顶:0
0
9
8
7
6
5
4
3
2
1
int main()
{
PLinkStack S;
StackNode x;
S = Init_LinkStack();
for (int i = 0; i < 10; i++) {
scanf_s("%d", &x.data);
Push_LinkStack(S, x);
}
int top;
GetTop_LinkStack(S,&top);
printf("栈顶:%d\n", top);
Print_LinkStack(S);//先进后出
return 0;
}
10、完整代码
//栈的链表实现
#include "stdio.h"
#include "stdlib.h"
typedef struct node
{
int data;
struct node *next;
}StackNode, *PStackNode;
typedef struct {
PStackNode top;
}LinkStack, *PLinkStack;
//初始化空栈(链表
PLinkStack Init_LinkStack()
{
PLinkStack S;
S = (PLinkStack)malloc(sizeof(LinkStack));
if (S) S->top = NULL;
return (S);
}
//判栈空
int Empty_LinkStack(PLinkStack S)
{
return (S->top == NULL);
}
//入栈
int Push_LinkStack(PLinkStack S, StackNode x)
{
PStackNode p;
p = (PStackNode)malloc(sizeof(StackNode));
if (!p)
{
printf("内存溢出!");
}
//一节一节的加
p->data = x.data;
p->next = S->top;
S->top = p;
return 1;
}
//出栈
int Pop_LinkStack(PLinkStack S, int *x)
{
PStackNode p;
if (Empty_LinkStack(S))
{
printf("栈空,不能出栈!");
return 0;
}
*x = S->top->data;
p = S->top;
S->top = S->top->next;
free(p);
return 1;
}
//取栈顶元素
int GetTop_LinkStack(PLinkStack S, int *x)
{
if (Empty_LinkStack(S)) {
printf("栈空,不能出栈!");
return 0;
}
*x = S->top->data;
return 1;
}
//栈销毁
void Destroy_LinkStack(PLinkStack *LS)
{
PStackNode p, q;
if (*LS) {
p = (*LS)->top;
while (p)
{
q = p;
p = p->next;
free(q);
}
free(*LS);
}
*LS = NULL;
return;
}
void Print_LinkStack(PLinkStack S)
{
PStackNode head = S->top;
while (head != NULL)
{
printf("%d\n", head->data);
head = head->next;
}
}
int main()
{
PLinkStack S;
StackNode x;
S = Init_LinkStack();
for (int i = 0; i < 10; i++) {
scanf_s("%d", &x.data);
Push_LinkStack(S, x);
}
int top;
GetTop_LinkStack(S,&top);
printf("栈顶:%d\n", top);
Print_LinkStack(S);//先进后出
return 0;
}