C语言 链栈的基本功能和详细代码(包含注释)

1.栈的概念及结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶
我们可以把栈想象成手枪子弹弹夹,一颗颗按进去后,先打出来的绝对是最后放进去的那一颗子弹,按子弹和出子弹都是在弹夹口操作。
栈一般用于括号匹配问题,力扣牛客上都有练习题。

如图:栈其实就是个只能在某一端操作的数组线性表

在这里插入图片描述
元素1入栈 此时栈顶元素为1
在这里插入图片描述
栈顶元素1出栈,此时元素7为栈顶元素
在这里插入图片描述

2.栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小,而链表必须要先找到最后一个节点才可以尾插。
可以使用静态数组也可以使用动态数组来实现,但静态的一般不实用,故使用动态数组实现
头文件
1.动态栈的结构
2.栈的基本功能的定义

#pragma once
#include <stdio.h>
#include<malloc.h>

typedef int STDataType;
//支持动态生长的栈结构
typedef struct Stack
{
	STDataType* array;//数组
	STDataType size;//有效元素个数
	STDataType capacity;//容量
}Stack;

void CheckCapacity(Stack* ps); //容量检测
void StackInit(Stack* ps);//初始化栈
void StackPush(Stack* ps, STDataType x);//入栈
void StackPop(Stack* ps);//出栈
STDataType StackTop(Stack* ps);//获取栈顶元素
int StackEmpty(Stack* ps);//判断栈是否为空
int StackSize(Stack* ps);//求栈的有效元素
void StackDestory(Stack* ps);//栈的销毁

具体的函数定义实现
常见的问题详见注释


#include "stack.h"
#define DEFSTACKSIZE 50   //先初始为50字节的容量
//容量检测
void CheckCapacity(Stack* ps)
{
	if (ps->size >= ps->capacity)//判断是否扩容
	{
		ps->capacity *= 2;    //2倍扩容
		ps->array = (STDataType *)realloc(ps->array, ps->capacity * sizeof(STDataType));      //ralloc:在array后继续申请空间
	}
}
void StackInit(Stack* ps)//初始化
{
	ps->array = (STDataType *)calloc(DEFSTACKSIZE, sizeof(STDataType));//calloc:申请数组空间并初始化为0
	ps->capacity = DEFSTACKSIZE;
	ps->size = 0;
}
void StackPush(Stack* ps, STDataType x) //数组尾部添加数据 即数组尾插入栈
{
	CheckCapacity(ps);
	ps->array[ps->size] = x;
	ps->size++;
}
void StackPop(Stack* ps)//出栈 
{
	if (ps->size == 0)
	{
		return;
	}
	ps->size--;
}
STDataType StackTop(Stack* ps)//获取栈顶元素
{
	if (ps->size == 0)//栈为空时即没有任何元素
	{
		return (STDataType)0;
	}
	return ps->array[ps->size - 1];//有元素时,返回栈顶元素
}
int StackEmpty(Stack* ps)//栈判空
{
	return ps->size == 0;
}
int StackSize(Stack* ps)//获取里有效元素个数
{
	return ps->size;
}
void StackDestory(Stack* ps)//栈的销毁
{
	if (ps->array)
	{
		free(ps->array);//一定要释放申请的内存
		ps->array = NULL;//且要置空,否则时悬空指针 即释放了内存,但是还是指向的之前指向的那个地址
		ps->size = 0;
		ps->capacity = 0;
	}
}

对写出的功能的简单测试

#include "stack.h"
int main()
{
	Stack ps;
	StackInit(&ps);
	StackPush(&ps, 1);
	StackPush(&ps, 2);
	StackPush(&ps, 3);
	StackPush(&ps, 4);//1 2 3 4依次入栈 

	printf("%d\n",StackTop(&ps));//栈顶元素 4
	StackPop(&ps);  //4出栈
	printf("%d\n", StackTop(&ps));//3为栈顶
	StackPop(&ps);//3出栈
	printf("%d\n", StackTop(&ps));//2为栈顶
	StackPop(&ps);//2出栈
	return 0;
}

3.总结

反正就是要多练,熟悉数组之后,再熟悉栈的规则之后就能理清关系了,不会了就多练,总会会的,,,,,,,,

发布了29 篇原创文章 · 获赞 8 · 访问量 1997

猜你喜欢

转载自blog.csdn.net/qq_44785014/article/details/104089972