初阶数据结构(C语言实现)——4.1栈

目录

  • 1.栈
    • 1.1栈的概念及结构
    • [1.2 栈的实现](#1.2 栈的实现)
      • [1.1.0 栈的初始化](#1.1.0 栈的初始化)
      • [1.1.1 销毁](#1.1.1 销毁)
      • [1.1.2 入栈](#1.1.2 入栈)
      • [1.1.3 出栈](#1.1.3 出栈)
      • [1.1.4 获取栈中有效元素个数](#1.1.4 获取栈中有效元素个数)
      • [1.1.5 检测栈是否为空,如果为空返回非零结果,如果不为空返回0](#1.1.5 检测栈是否为空,如果为空返回非零结果,如果不为空返回0)
      • [1.1.6 获取栈顶元素](#1.1.6 获取栈顶元素)
      • [1.1.7 验证](#1.1.7 验证)
  • [附录 栈的C语言实现源码](#附录 栈的C语言实现源码)

1.栈

1.1栈的概念及结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

  • 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
  • 出栈:栈的删除操作叫做出栈。出数据也在栈顶

1.2 栈的实现

在VS2022中新建一个工程

  • stack20250308.h(栈的类型定义、接口函数声明、引用的头文件)
  • stack20250308.c(栈的接口函数的实现)
  • stackTest20250308.c(主函数、测试各个接口功能)
  • 实现接口
c 复制代码
// 支持动态增长的栈
typedef int  STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;
c 复制代码
// 初始化栈
void STInit(ST* ps);
//销毁
void STDestroy(ST* ps);
// 入栈,插入
void STPush(ST* ps, STDataType x);
// 出栈,删除
void STPop(ST* ps);
//获取栈中有效元素个数
int STSize(ST* ps);
//检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool STEmpty(ST* ps);
//获取栈顶元素
STDataType STTop(ST* ps);

1.1.0 栈的初始化

c 复制代码
// 初始化栈
void STInit(ST* ps)
{
	assert(ps);
	ps->a = (STDataType*)malloc(sizeof(STDataType)*4);
	if (ps->a == NULL)
	{
		perror("STInit::malloc fail!");
		return;
	}
	ps->capacity = 4;
	ps->top = 0;//top是栈顶元素的下一个位置

	//ps->top =-1;//top是栈顶元素位置
}

1.1.1 销毁

c 复制代码
//销毁
void STDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

1.1.2 入栈

c 复制代码
// 入栈,插入
void STPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		STDataType* tem = (STDataType*)realloc(ps->a,sizeof(STDataType) * ps->capacity*2);//扩容当前的2倍
		if (ps->a == NULL)
		{
			perror("STInit::relloc fail!");
			return;
		}
		ps->a = tem;
		ps->capacity *= 2; //修改容量
	}
	ps->a[ps->top] = x;
	ps->top++;
}

1.1.3 出栈

c 复制代码
// 出栈,删除
void STPop(ST* ps)

{
	assert(ps);
	assert(!STEmpty(ps));//检查是否为空,为空就报错,
	ps->top--;//直接--,但是空栈的时候就不能继续--,所以在之前进行是否为空的检查。
}

1.1.4 获取栈中有效元素个数

c 复制代码
//获取栈中有效元素个数
int STSize(ST* ps)
{
	assert(ps);
	//top就是size
	return ps->top;
}

1.1.5 检测栈是否为空,如果为空返回非零结果,如果不为空返回0

c 复制代码
//检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

1.1.6 获取栈顶元素

c 复制代码
//获取栈顶元素
STDataType STTop(ST* ps)
{
	assert(ps);

	return ps->a[ps->top - 1];//top是最后一个元素的下一个位置,所以-1
}

1.1.7 验证

  • 验证的时候,我们栈是不能打印的,我们需要一个一个出栈打印栈顶元素
c 复制代码
void STTest()
{
    ST st;
    STInit(&st);
    STPush(&st, 1);
    STPush(&st, 2);
    STPush(&st, 3);
    STPush(&st, 4);
    STPush(&st, 5);

    while (!STEmpty(&st))
    {
        printf("%d ", STTop(&st));
        STPop(&st);
    }

    STDestroy(&st);

}

插入

删除

栈有效个数验证

附录 栈的C语言实现源码

.h文件

c 复制代码
#pragma once
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<assert.h>

//静态的
//#define N 10
//typedef struct Stack
//{
//	int a[N];
//	int top;
//
//}Stack;

// 支持动态增长的栈
typedef int  STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;
// 初始化栈
void STInit(ST* ps);
//销毁
void STDestroy(ST* ps);
// 入栈,插入
void STPush(ST* ps, STDataType x);
// 出栈,删除
void STPop(ST* ps);
//获取栈中有效元素个数
int STSize(ST* ps);
//检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool STEmpty(ST* ps);
//获取栈顶元素
STDataType STTop(ST* ps);

.c文件

c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"stack20250308.h"

// 初始化栈
void STInit(ST* ps)
{
	assert(ps);
	ps->a = (STDataType*)malloc(sizeof(STDataType)*4);
	if (ps->a == NULL)
	{
		perror("STInit::malloc fail!");
		return;
	}
	ps->capacity = 4;
	ps->top = 0;//top是栈顶元素的下一个位置

	//ps->top =-1;//top是栈顶元素位置
}


//销毁
void STDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}
// 入栈,插入
void STPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		STDataType* tem = (STDataType*)realloc(ps->a,sizeof(STDataType) * ps->capacity*2);//扩容当前的2倍
		if (ps->a == NULL)
		{
			perror("STInit::relloc fail!");
			return;
		}
		ps->a = tem;
		ps->capacity *= 2; //修改容量
	}
	ps->a[ps->top] = x;
	ps->top++;
}
// 出栈,删除
void STPop(ST* ps)

{
	assert(ps);
	assert(!STEmpty(ps));//检查是否为空,为空就报错,
	ps->top--;//直接--,但是空栈的时候就不能继续--,所以在之前进行是否为空的检查。
}

//获取栈中有效元素个数
int STSize(ST* ps)
{
	assert(ps);
	//top就是size
	return ps->top;
}
//检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}
//获取栈顶元素
STDataType STTop(ST* ps)
{
	assert(ps);

	return ps->a[ps->top - 1];//top是最后一个元素的下一个位置,所以-1
}

test.c文件

c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"stack20250308.h"

void STTest()
{
    ST st;
    STInit(&st);
    STPush(&st, 1);
    STPush(&st, 2);
    STPush(&st, 3);
    STPush(&st, 4);
    STPush(&st, 5);
    STPop(&st);
    STPop(&st);
    int size = STSize(&st);
    printf("栈有效元素为:%d\n", size);
    while (!STEmpty(&st))
    {
        printf("%d ", STTop(&st));
        STPop(&st);
    }
    STDestroy(&st);
}

int main()
{
    STTest();
    return 0;
}
相关推荐
MY_TEUCK19 小时前
【Java 后端】SpringBoot 登录认证与会话跟踪实战(JWT + Filter/Interceptor)
java·开发语言·spring boot
今天长肉了吗20 小时前
银行风控项目踩坑实录:指标跑了6小时,风险评分全挂了
java
随读手机20 小时前
多式联运信息交互平台完整方案(2026版)
java·ai·eclipse·云计算·区块链
郝学胜-神的一滴20 小时前
深度学习优化核心:梯度下降与网络训练全解析
数据结构·人工智能·python·深度学习·算法·机器学习
Je1lyfish21 小时前
CMU15-445 (2025 Fall/2026 Spring) Project#3 - QueryExecution
linux·c语言·开发语言·数据结构·数据库·c++·算法
许彰午21 小时前
03-二叉树——从递归遍历到非递归实现
java·算法
nj012821 小时前
Spring 循环依赖详解:三级缓存、早期引用、AOP 代理与懒加载
java·spring·缓存
野生技术架构师21 小时前
2026年最全Java面试题及答案汇总(建议收藏,面试前看这篇就够了)
java·开发语言·面试
一只叫煤球的猫1 天前
ThreadForge 源码解读一:ThreadScope 如何把并发任务放进清晰边界?
java·面试·开源
墨染千千秋1 天前
C/C++ Keywords
c语言·c++