初阶数据结构(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;
}
相关推荐
浪九天28 分钟前
Java直通车系列13【Spring MVC】(Spring MVC常用注解)
java·后端·spring
Kurbaneli1 小时前
深入理解 C 语言函数的定义
linux·c语言·ubuntu
Archer1941 小时前
C语言——链表
c语言·开发语言·链表
堕落年代1 小时前
Maven匹配机制和仓库库设置
java·maven
功德+n1 小时前
Maven 使用指南:基础 + 进阶 + 高级用法
java·开发语言·maven
夜晚中的人海1 小时前
【C语言】------ 实现扫雷游戏
android·c语言·游戏
面会菜.1 小时前
C语言(队列)
c语言·开发语言
开心比对错重要2 小时前
leetcode69.x 的平方根
数据结构·算法·leetcode
香精煎鱼香翅捞饭2 小时前
java通用自研接口限流组件
java·开发语言
ChinaRainbowSea2 小时前
Linux: Centos7 Cannot find a valid baseurl for repo: base/7/x86_64 解决方案
java·linux·运维·服务器·docker·架构