栈就像叠猫猫,遵循"先入后出"的原则;队列就像猫猫排队,遵循”先入先出“的原则。栈和队列均可以通过数组(顺序表)和链表(链表)来实现。

1.栈

栈的主要操作可以分为以下几种:

方法 描述 时间复杂度
push() 元素入栈(添加至栈顶) O(1)
pop() 栈顶元素出栈 O(1)
peek() 访问栈顶元素 O(1)

1.1基于数组实现栈

1.1.1定义栈的结构体

typedef int ElemType;
typedef struct {
ElemType* data;
int length;
}SqStack;

1.1.2栈的初始化

SqStack *InitStack() {
SqStack* stack = malloc(sizeof(SqStack));
stack->data = (ElemType*)malloc(sizeof(ElemType)*Max_Size);
stack->length = 0;
return stack;
}

1.1.3栈的释放

//栈的释放
void DestoryStack(SqStack* stack) {
free(stack->data);
free(stack);
}

1.1.4元素入栈

void push(SqStack* stack,ElemType e) {
if(stack->length == Max_Size) {
printf("栈满!\n");
return;
}
stack->data[stack->length++] = e;
}

stack->data[stack->length++] = e;:如果栈未满,将元素 e 存储在栈的当前位置(由 stack->length 指示),然后增加 stack->length 的值,表示栈中元素的数量增加了。

1.1.5元素出栈

 //元素出栈
ElemType pop(SqStack* stack) {
if (stack->length == 0) {
printf("栈空!\n");
return -1;
}
return stack->data[stack->length--];
}

1.1.6访问栈顶元素

//访问栈顶元素
ElemType peek(SqStack* stack) {
if(stack->length == 0) {
printf("栈空!\n");
return -1;
}
return stack->data[stack->length-1];
}

1.2基于链表实现栈

1.2.1链表的结构体定义

typedef int ElemType;
//定义链表结构体
typedef struct StackNode{
ElemType* data;
struct StackNode* next;
}StackNode, *LinkStackPtr;
//定义栈的结构体
typedef struct {
StackNode* top;
int length;
}LinkStack;

1.2.2初始化栈

//初始化栈
LinkStack* InitStack() {
LinkStack* s = malloc(sizeof(LinkStack));
if (s == NULL) {
printf("内存分配失败!\n");
return NULL;
}
s->top = NULL;
s->length = 0;
return s;
}

1.2.3销毁栈

//销毁栈
void DestroyStack(LinkStack* s) {
//由栈顶到栈底,逐次释放
while (s->top) {
StackNode *n = s->top;
free(n);
s->top = s->top->next;
}
free(s);
}

1.2.4元素出栈

//元素出栈
ElemType pop(LinkStack* s) {
StackNode *node = malloc(sizeof(StackNode));
node->data = s->top->data;//将元素复制到node链表
StackNode *tmp = s->top;
s->top = s->top->next;//这里将top更新
free(tmp);
s->length--;
return node->data;
}

1.2.5访问栈顶元素

//访问栈顶元素
ElemType peek(LinkStack* s) {
if(s->length == 0) {
printf("栈空");
return -1;
}
return s->top->data;
}

2.队列

为了实现队列,我们需要一种数据结构,可以在一端添加元素,并在另一端删除元素,链表和数组都符合要求。

2.1基于数组的队列

2.1.1队列的结构体定义

//结构体定义
typedef int ElemType;
typedef struct {
ElemType* data;
ElemType front; //队首指针
ElemType end; //队尾指针
int length; //队列长度
}ArrayQueue;

2.1.2队列的初始化

//队列的初始化
ArrayQueue *InitQueue(int queCapcity) {
ArrayQueue* queue = (ArrayQueue*)malloc(sizeof(ArrayQueue));
queue->length = queCapcity;
queue->front = queue->end = 0;
queue->data = (ElemType*)malloc(sizeof(ElemType)*queue->length);
return queue;
}

2.1.3销毁队列

//销毁队列
bool DestoryQueue(ArrayQueue* queue) {
free(queue->data);
free(queue);
return true;
}

2.1.4入队

//入队
void push(ArrayQueue* queue,ElemType e) {
if(queue->length == queue->end) {
printf("队满");
return;
}
int rear = (queue->front + queue->end) % queue->length; queue->data[rear] = e;
queue->end++;
}

2.1.5访问队首元素

//访问队首元素
ElemType geek(ArrayQueue* queue) {
return queue->data[queue->front];
}

2.1.6出队

//出队
ElemType pop(ArrayQueue* queue) {
ElemType num = peek(queue);
queue->front = (queue->front + 1) % queue->length;
return num;
}

2.2基于链表的队列

2.1.1队列结构体的定义

我们可以将链表的“头节点”和“尾节点”分别视为“队首”和“队尾”,规定队尾仅可添加节点,队首仅可删除节点。

typedef int ElumType;
typedef struct Linklist{
ElumType* data;
struct Linklist* next;
}LNode;
typedef struct {
LNode *front,*rear;
int quelength;
}LinkListQueue;

2.1.2队列初始化

//队列的初始化
LinkListQueue* InitLinkListQueue() {
LinkListQueue* queue = (LinkListQueue*)malloc(sizeof(LinkListQueue));
queue->front = NULL;
queue->rear = NULL;
queue->quelength = 0;
return queue;
}

2.1.3队列的删除

//队列的删除
void DestroyLinkListQueue(LinkListQueue *queue) {
while (queue->front != NULL) {
LNode* temp = queue->front;
queue->front = queue->front->next;
free(temp);
}
free(queue);
}

2.1.4元素入队

//入队
bool push(LinkListQueue* queue,ElumType e) {
LNode* node = (LNode*)malloc(sizeof(LNode));
node->data = e;
//队列为空,头尾指针都指向node
if(queue->quelength == 0) {
queue->front = node;
queue->rear = node;
queue->quelength++;
}
else {
queue->rear->next = node;
queue->rear = node;
queue->quelength++;
}
return true;
}

2.1.5访问队首元素

//访问队首元素
ElumType peek(LinkListQueue* queue) {
if(queue->quelength == 0) {
printf("队空!\n");
return -1;
}
return queue->front->data;
}

2.1.6出队

//出队
ElumType pop(LinkListQueue* queue) {
ElumType num = peek(queue);
LNode *tmp = queue->front;
queue->front = queue->front->next;
free(tmp);
queue->quelength--;
return num;
}

以上是栈与队列的一些基本操作,原版代码上传至(https://gitee.com/shi-chengfu)

如果有错误请联系QQ:303613518

栈与队列(c语言实现)的更多相关文章

  1. 4-29 c语言之栈,队列,双向链表

    今天学习了数据结构中栈,队列的知识 相对于单链表来说,栈和队列就是添加的方式不同,队列就相当于排队,先排队的先出来(FIFO),而栈就相当于弹夹,先压进去的子弹后出来(FILO). 首先看一下栈(St ...

  2. <2014 05 16> 线性表、栈与队列——一个环形队列的C语言实现

    栈与队列都是具有特殊存取方式的线性表,栈属于先进后出(FILO),而队列则是先进先出(FIFO).栈能够将递归问题转化为非递归问题,这是它的一个重要特性.除了FILO.FIFO这样的最普遍存取方式外, ...

  3. C语言数据结构——第三章 栈和队列

    三.栈和队列 栈和队列是两种重要的线性结构.从数据结构的角度来看,栈和队列也是线性表,它的特殊性在于栈和队列的基本操作是线性表操作的子集,它们的操作相对于线性表来说是受到限制的,因此,可以称其为限定性 ...

  4. 《数据结构与算法分析:C语言描述_原书第二版》CH3表、栈和队列_reading notes

    表.栈和队列是最简单和最基本的三种数据结构.基本上,每一个有意义的程序都将明晰地至少使用一种这样的数据结构,比如栈在程序中总是要间接地用到,不管你在程序中是否做了声明. 本章学习重点: 理解抽象数据类 ...

  5. C语言数据结构基础学习笔记——栈和队列

    之前我们学过了普通的线性表,接下来我们来了解一下两种特殊的线性表——栈和队列. 栈是只允许在一端进行插入或删除的线性表. 栈的顺序存储结构也叫作顺序栈,对于栈顶指针top,当栈为空栈时,top=-1: ...

  6. 数据结构(C语言版)-第3章 栈和队列

    3.1 栈和队列的定义和特点3.2 案例引入3.3 栈的表示和操作的实现3.4 栈与递归3.5 队列的的表示和操作的实现3.6 案例分析与实现 基本操作有入栈.出栈.读栈顶元素值.建栈.判断栈满.栈空 ...

  7. C++学习(三十)(C语言部分)之 栈和队列

    数据结构1.保存数据 2.处理数据数组+操作增查删改 栈和队列是一种操作受限的线性表 栈 是先进后出 是在一端进行插入删除的操作--->栈顶 另一端叫做栈底(栈和栈区是两个概念)(是一种数据结构 ...

  8. 栈和队列ADT -数据结构(C语言实现)

    数据结构与算法分析 栈模型 限制插入和删除只能在表的末端的表 表的末端叫做栈顶(top) 支持Push进栈和Pop入栈操作 //LIFO后进先出表 栈的实现 链表实现 类型声明 struct Node ...

  9. 数据结构(c语言版,严蔚敏)第3章栈和队列

    第3章栈和队列

  10. LeetCode 232题用栈实现队列(Implement Queue using Stacks) Java语言求解

    题目链接 https://leetcode-cn.com/problems/implement-queue-using-stacks/ 题目描述 使用栈实现队列的下列操作: push(x) -- 将一 ...

随机推荐

  1. cuda的slient模式下的安装

    实验室的师弟要搞cuda编译,不会安装cuda,其实这个主要原因还是服务器上是不允许个人随意安装软件的,尤其是nvidia的那些东西,很容易把整个服务器搞崩掉,虽然实验室的服务器集群我是唯一的一个管理 ...

  2. 3.2.0 版本预告!远程日志解决 Worker 故障获取不到日志的问题

    Apache DolphinScheduler 3.2.0 版本已经呼之欲出,8 月 中下旬,这个大版本就要和用户见面了.为了让大家提前了解到此版本更新的主要内容,我们已经制作了几期视频和内容做了大致 ...

  3. TGI 多-LoRA: 部署一次,搞定 30 个模型的推理服务

    你是否已厌倦管理多个 AI 模型所带来的复杂性和高成本? 那么, 如果你可以部署一次就搞定 30 个模型推理服务会如何? 在当今的 ML 世界中,哪些希望充分发挥其数据的价值的组织可能最终会进入一个& ...

  4. 与LLMs进行在IDE中直接、无需提示的交互是工具构建者探索的一个有希望的未来方向

    这个观点在卡内基梅隆大学与谷歌研究人员合作文章 <Using an LLM to Help With Code Understanding> 中提出. 论文地址:https://dl.ac ...

  5. 告别卡顿,畅享GitHub:国内开发者必看的五大加速访问与下载技巧

    告别卡顿,畅享GitHub:国内开发者必看的五大加速访问与下载技巧 本文介绍了五种加速在国内访问和下载 GitHub 的方法,包括:使用 Gitee 平台加速克隆代码.修改 hosts 文件.使用油猴 ...

  6. 让你的C程序,可以自动更新版本信息

    一.软件管理 稍微上点规模的软件开发往往周期都非常长, 中间会产生很多临时版本, 这些临时版本往往会有各种各样的bug, 由于项目参与的人员众多.水平参差不齐, 软件分支众多.功能复杂, 经常会有各种 ...

  7. Polly服务熔断

    //自定义异常 public class MyException : Exception { public MyException(string? message) : base(message) { ...

  8. Graphics2D绘图方法总结

    一.简介 在开发中可能会遇到这样一类场景,业务复杂度不算太高,技术难度不算太深,但是做起来就很容易把人整破防,伤害很高侮辱性很强的:绘图. 绘图最怕有人挑刺:这里变形,那里不对,全图失真. 最近在处理 ...

  9. Windows 设置 FRP 自动启动

    由于 frps/frpc 不是 Windows 服务应用程序,因此我们不能直接使用 New-Service 命令创建 frps/frpc 服务.我们可以使用下面的方法将 frps/frpc 封装为 W ...

  10. Kubernetes-3:使用kubeadm部署k8s环境及常见报错解决方法

    k8s集群安装 环境说明: k8s-Master-Centos8 ip:192.168.152.53 k8s-Node1-Centos7 ip:192.168.152.253 k8s-Node2-Ce ...