C语言完成栈的链表实现

74 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情

1、结构体定义

栈可以视为一个特殊功能的链表,因为栈的主要的操作是对栈顶进行插入、删除,显然以链表的头部作为栈顶更为方便,所以也就不再需要头节点,同时为了方便操作和强调栈顶是栈的一个属性,可以这样定义:

//该部分与单链表结构体相同
typedef struct node
{
	int data;
	struct node *next;
}StackNode, *PStackNode;
//top始终指向最后一个入站的元素
typedef struct {
	PStackNode top;
}LinkStack, *PLinkStack;

image.png

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;
}