初阶数据结构(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;
}
相关推荐
期待のcode7 分钟前
Dockerfile镜像构建
java·docker·容器
小满、10 分钟前
对象住哪里?——深入剖析 JVM 内存结构与对象分配机制
java·jvm·#java对象分配·#hotspot实现
How_doyou_do12 分钟前
模态框的两种管理思路
java·服务器·前端
雾岛听蓝12 分钟前
算法复杂度解析:时间与空间的衡量
c语言·数据结构·经验分享·笔记
m0_7482480217 分钟前
C++ 异常处理全解析:从语法到设计哲学
java·c++·word
仟濹19 分钟前
IDEA 软件下载 + 安装 | 操作步骤
java·ide·intellij-idea
Nebula_g27 分钟前
C语言应用实例:学生管理系统1(指针、结构体综合应用,动态内存分配)
c语言·开发语言·学习·算法·基础
毕设源码-赖学姐28 分钟前
【开题答辩全过程】以 法院信访投诉平台为例,包含答辩的问题和答案
java·eclipse
惊讶的猫31 分钟前
字符串- 字符串转换整数 (atoi)
数据结构·算法
依_旧40 分钟前
MySQL下载安装配置(超级超级入门级)
java·后端