堆和队列(Stack && Queue)数据结构的基本操作实现详解

本文详细介绍了栈和队列这两种数据结构,包括它们的基本操作如压栈、出栈、入队、出队等,并通过具体的函数实现阐述了如何用数组和链式结构来设计堆和队列。此外,还讨论了栈和队列在实际应用中的场景,如广度优先遍历和公平排队等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

今天介绍一下栈和堆

栈:是一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶。另一段为栈底
栈的数据遵守后进先出LIFO(last in first out)的原则

压栈:栈的插入操作叫做进栈/压栈,如数据在栈顶
出栈:栈的删除操作叫出栈,出数据也在栈顶
在这里插入图片描述
这里有很多人问栈和队列属于线性结构吗?可以用链表实现吗?
答案是肯定的,两者都可实现栈和队列,数据结构需要适配不同的应用场景。而顺序表和链表没有说哪个最好,都各有千秋。
顺序表在内存中是连续存储的,密度高,但是空间受限。
链式结构不受限于空间,随意扩容,但是存储是不连续的,密度低

堆:只允许在一端进行插入操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出First in first out

入队列:进行插入操作的一端成为队尾
出队列:进行删除操作的一端成为队头
在这里插入图片描述
栈和队列的出入顺序区别:
在这里插入图片描述
而队列,一种入队顺序,一种出队顺序

举个例子:
有的题目会问一个栈的入栈序列为ABCDE,出栈序列可能是什么呢?

可能是ABCDE,因为A先进,然后A出,B进B出,依次类推
可能是ABC入,然后CBA出,DE再进,ED出
但不可能是ECDBA,因为E先出,说明所有元素都已入栈,那么不可能是C先出而是D先出

典型应用场景:

  1. 队列实际中要保证公平排队的地方都可以用他,如抽号机
  2. 广度优先遍历

二、堆(stack)

1. 整体设计框架

请添加图片描述
还是和之前一样分为三个文件,而不是写在一个main函数里面,这样可读性更高,便于调试

main.c 专门用于函数调用、调试
stack.h 只用于函数声明
stack.c 用于函数实现

2. 函数实现

这里我们用数组进行数据存储

2.1 head File

我们先来看一下头文件的架构以及需要实现的函数功能

typedef int STDatatype;
typedef struct Stack{
   
   
    STDatatype* a;
    int top; //栈顶 , 类似于size
    int capacity;
}ST;

void StackInit(ST* ps);
void StackDestory(ST* ps);
void StackPush(ST* ps, STDatatype x);
void StackPop(ST* ps);
bool StackEmpty(ST* ps);
int StackSize(ST* ps);
STDatatype StackTop(ST* ps); //取栈顶的数值

这里的STDataType是便于后期全局修改数据类型
Stack数据结构里有三个成员,第一个成员a为动态数组,后续进行空间开辟,top是指stack中的栈顶也就是数组的最后一个值,capacity为数组的总容量

2.2 StackInit

void StackInit(ST* ps){
   
   
    assert(ps); //先断言,给的结构体是否为空,是空那就不用玩了,因此这里避免用户使用误传NULL
    ps->a = NULL;
    ps->top = 0;
    ps->capacity = 0;
}

2.3 StackDestory

如果a数组不为空,free整个数组,并将数组a置空

void StackDestory(ST* ps){
   
   
    assert(ps);
    if(ps->a){
   
   
        free(ps->a);
    }
    ps->a = NULL;
    ps->top = 0;
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值