C语言 之 【栈的简介、栈的实现(初始化、销毁、入栈、出栈、判空、栈的大小、访问栈顶元素、打印)】

目录

1.栈的简介

2.栈的实现

2.1实现须知

2.2头文件预览

2.2.1头文件细节

[2.3 栈的初始化](#2.3 栈的初始化)

[2.4 栈的销毁](#2.4 栈的销毁)

[2.5 入栈](#2.5 入栈)

[2.6 出栈](#2.6 出栈)

[2.7 判空](#2.7 判空)

[2.8 栈的大小](#2.8 栈的大小)

[2.9 访问栈顶元素](#2.9 访问栈顶元素)

[2.10 出栈的打印](#2.10 出栈的打印)


1.栈的简介

栈是一种数据结构,是一种特殊的线性表,

栈只允许在一端进行插入和删除数据的操作

进行数据插入和删除操作的一端称为栈顶 ,另一端称为栈底

栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

可以把栈理解为一个垃圾桶,先丢进去的垃圾在桶底,

后丢进去的东西会覆盖在表面(即在桶顶)

只有先倒出桶顶的垃圾,才能倒出桶底的垃圾
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶

出栈:栈的删除操作叫做出栈。出数据也在栈顶

2.栈的实现

2.1实现须知

前面说了,栈是是一种线性表,所以既可以用数组实现栈 也可以用链表实现栈

但是,数组的缓存利用较高,所以选择用数组实现栈
显然,实践中都是按需申请空间,所以使用动态数组实现栈

2.2头文件预览

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

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;
//初始化
void StackInit(ST* st);
//销毁
void StackDestroy(ST* st);
//入栈
void StackPush(ST* st, STDataType val);
//出栈
void StackPop(ST* st);
//判空
bool STEmpty(ST* st);
//大小
int STSize(ST* st);
//访问栈顶元素
STDataType STTop(ST* st);

2.2.1头文件细节

(1)防止头文件内容在同一个编译单元内被多次展开

复制代码
#pragma once

(2)包含必要的头文件(库函数、开空间、断言、布尔值)
(3)数据类型重命名,(以后只改这一处,就可以改变栈所存储的数据类型)

复制代码
typedef int STDataType;

(4)与顺序表相同,多个数据存储在结构体中,其中

变量a,指向堆上一块用来存储数据的空间,

变量top,标明栈顶元素的位置或栈顶元素位置的下一个位置 (依照具体实现而定)

变量capacity,标明栈的容量


(5)结构体typedef一下,不然名字太长了
(6)关于函数接口的设计

一:用户在函数外可以直接创建一个栈对象,然后传入它的地址,各函数用一级指针接收后,在函数内部使用指针就可以改变栈对象

二:如果用户在函数外创建的是一个栈类型的指针,初始化函数体内部就malloc一个栈对象,然后要么返回malloc后的指针,要么参数使用二级指针,以达到目的

方法一可以使各接口参数列表基本一致,所以我选择它(个人按需选择)

2.3 栈的初始化

复制代码
void StackInit(ST* st)
{
	//传入的结构体指针一定不为空
	assert(st);
	//为栈存储数据开好空间,初始化的时候未指向有效内存,可以直接使用st->a
	st->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (st->a == NULL)
	{
		perror("malloc fail");
		exit(1);
	}

	st->capacity = 4;
	st->top = 0;     //栈顶元素的下一个位置,站的元素个数
}

(1)结构体指针一定不为空 ,所以加断言

(1)最开始结构体中的变量a并未指向有效内存,可以直接用它接收返回值

(1)注意空间开辟失败的问题
top的初始值一般常取0 或1

(1)top == 0

此时 top 指向的是栈顶元素的下一个位置,因为

当第一个元素入栈时,top++,top的值就是1,正好是该元素下标的下一个位置

(2)top == -1

此时 top 指向的是栈顶元素的位置,因为

当第一个元素入栈时,top++,top的值就是0,正好是该元素的下标

2.4 栈的销毁

复制代码
void StackDestroy(ST* st)
{
	assert(st);

	free(st->a);
	st->a = NULL;
	st->capacity = st->top = 0;
}

断言结构体指针,释放堆上申请的空间,还原成空对象即可

2.5 入栈

复制代码
void StackPush(ST* st, STDataType val)
{
	assert(st);

	if (st->top == st->capacity)
	{
		STDataType* temp = (STDataType*)realloc(st->a, sizeof(STDataType) * st->capacity * 2);
		if (temp == NULL)
		{
			perror("realloc fail");
			exit(1);
		}
		st->a = temp;//谨防内存泄漏,需要使用临时变量
		st->capacity *= 2;
	}

	st->a[st->top] = val;
	st->top++;
}

(1)老生常谈,断言结构体指针

(2)入栈之前,判断一下扩容操作

1.top的值正好是栈中元素的个数,当个数等于容量时就进行扩容

2.可以进行2倍扩容,并注意使用临时变量接收返回值,防止接受失败导致内存泄漏

(3)top初始值是0,指向栈顶元素的下一个位置,那么直接在top位置插入元素

然后top++

2.6 出栈

复制代码
void StackPop(ST* st)
{
	assert(st);
	assert(!STEmpty(st));

	st->top--;

}

(1)结构体指针不为空,栈中必须有元素才能进行出栈操作

(2)堆上申请的是一段连续的空间,并不支持一段空间释放,

只要不太浪费内存,没必要重新开空间存储剩下的数据,直接top--

2.7 判空

复制代码
bool STEmpty(ST* st)
{
	assert(st);

	return st->top == 0;
}

(1)判空结构体指针

(2)top的值就是栈中元素的个数

2.8 栈的大小

复制代码
int STSize(ST* st)
{
	assert(st);

	return st->top;
}

(1)判空结构体指针

(2)top的值就是栈中元素的个数

2.9 访问栈顶元素

复制代码
STDataType STTop(ST* st)
{
	assert(st);
    assert(!StackEmpty(st));

	return st->a[st->top - 1];
}

(1)判空结构体指针

(2)top的初始值是0,是栈顶元素下标的后一个位置

2.10 栈的打印

栈并不支持遍历访问,只能访问栈顶元素即不提供遍历访问的接口

想要知道所有元素

只有边访问栈顶元素,边出栈

当然,如果需要保留元素,可提前保存一下

复制代码
ST st;
StackInit(&st);
StackPush(&st, 1);
StackPush(&st, 2);
StackPush(&st, 3);
StackPush(&st, 4);
StackPush(&st, 5);
StackPush(&st, 6);

while (!STEmpty(&st))
{
	printf("%d ", STTop(&st));
	StackPop(&st);
}
相关推荐
我是一只鱼02231 小时前
LeetCode算法题 (设计链表)Day16!!!C/C++
数据结构·c++·算法·leetcode·链表
八股文领域大手子2 小时前
单机 vs 分布式:Java 后端限流的选择题
java·开发语言·数据结构·算法·spring
纪元A梦3 小时前
华为OD机试真题——告警抑制(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
java·c语言·javascript·c++·python·华为od
keep intensify4 小时前
【数据结构】--- 双向链表的增删查改
c语言·数据结构·算法·链表
Despacito0o5 小时前
C语言发展史:从Unix起源到现代标准演进
c语言·stm32·unix·嵌入式实时数据库
江沉晚呤时6 小时前
深入解析 SqlSugar 与泛型封装:实现通用数据访问层
数据结构·数据库·oracle·排序算法·.netcore
小徐Chao努力6 小时前
【堆】最大堆、最小堆以及GO语言的实现
数据结构·算法·golang·
jerry6097 小时前
算法四 习题 1.3
数据结构·c++·算法
小冯的编程学习之路8 小时前
【C++】:C++17新特性
c语言·开发语言·c++·算法