C语言——栈和队列

news2024/9/24 13:25:52

文章目录

  • 一、栈
    • 1. 栈的概念
    • 2. 栈的基本功能
    • 3. 栈的实现
  • 二、 队列
    • 1. 队列的概念
    • 2. 队列的基本功能
    • 3. 队列的实现

一、栈

1. 栈的概念

栈是一种特殊的线性表,限定仅在表尾进行插入和删除的线性表。这一端称之为栈顶,另一端称为栈底。
栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构
在这里插入图片描述

2. 栈的基本功能

// 初始化栈 
void StackInit(Stack* ps);
// 入栈 
void StackPush(Stack* ps, STDataType data);
// 出栈 
void StackPop(Stack* ps);
// 获取栈顶元素 
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数 
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps);
// 销毁栈 
void StackDestroy(Stack* ps);

3. 栈的实现

栈的实现一般使用数组或者链表,因为cpu高速缓存的原因,使用数组也非常ok。

创建三个文件
头文件:
Stack.h
源文件:
Stack.c
test.c(测试功能是否能实现)

结构体的定义和函数声明:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;		// 栈顶
	int capacity;  // 容量 
}Stack;
// 初始化栈 
void StackInit(Stack* ps);
// 入栈 
void StackPush(Stack* ps, STDataType data);
// 出栈 
void StackPop(Stack* ps);
// 获取栈顶元素 
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数 
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps);
// 销毁栈 
void StackDestroy(Stack* ps);

实现方法:

// 初始化栈 
void StackInit(Stack* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	//指向栈顶元素的下一个位置
	ps->top = 0;
	//top指向栈顶元素
	//ps->top = -1;
}

ps->a我们有两种初始化方法,一种是直接malloc一个空间,可以是四个或者八个对象的空间,也可以像我一样,先不开,等会入栈的时候再开。
在进行入栈以前,先把top指向为栈顶的下一个数据,如果指向栈顶数据的话,初始化就不能为0。
在这里插入图片描述

// 销毁栈 
void StackDestroy(Stack* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}
// 入栈 
void StackPush(Stack* ps, STDataType data)
{
	assert(ps);
	//扩容
	
	if (ps->capacity == ps->top)
	{
		//初始化不开空间,当我插入数据时再开
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		//用realloc因为在第一个指针为空时,realloc可以实现malloc的功能
		STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
	ps->a[ps->top] = data;//把数据直接放在top
	ps->top++;//top往后走到栈顶下一个数据

}
// 出栈 
void StackPop(Stack* ps)
{
	assert(ps);
	assert(ps->top > 0);//只有当栈不为空时才能出栈
	ps->top--;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps)
{
	assert(ps);
	return ps->top == 0;
}
/ 获取栈顶元素 
STDataType StackTop(Stack* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top-1];
}
// 获取栈中有效元素个数 
int StackSize(Stack* ps)
{
	assert(ps);
	return ps->top;
}

二、 队列

1. 队列的概念

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。
在这里插入图片描述

2. 队列的基本功能

//初始化
void QueueInit(Queue* qp);
//销毁
void QueueDestroy(Queue* qp);
//队尾插入
void QueuePush(Queue* qp, QDatatype x);
//对头删除
void QueuePop(Queue* qp);
//取头和尾的数据
QDatatype QueueFront(Queue* qp);
QDatatype QueueBack(Queue* qp);
//获取队列元素个数
int QueueSize(Queue* qp);
//判空
bool QueueEmpty(Queue* qp);

3. 队列的实现

队列的实现用单链表就能很好的解决

创建三个文件
头文件:Queue.h
源文件:
Queue.c
test.c(测试功能是否能实现)

#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
#include <stdlib.h>
typedef int QDatatype;
typedef struct QNode
{
	struct Queue* next;
	QDatatype val;
}QNode;
typedef struct Queue
{
	QNode* phead;
	QNode* ptail;
	int size;//可以提高效率,删除就减去size,插入就增加size
}Queue;
//初始化Queue
//销毁
void QueueInit(Queue* qp);
void QueueDestroy(Queue* qp);
//void QueuePush(Queue** phead, Queue** ptail, QDatatype x);
//void QueuePop(Queue** phead, Queue** ptail);
//队尾插入和对头删除需要标记节点,还有更简便的方法,再创建一个结构体,名为Queue
//改变结构体的内容只需要传一级指针就行
//队尾插入
void QueuePush(Queue* qp, QDatatype x);
//对头删除
void QueuePop(Queue* qp);
//取头和尾的数据
QDatatype QueueFront(Queue* qp);
QDatatype QueueBack(Queue* qp);
//获取队列元素个数
int QueueSize(Queue* qp);
//判空
bool QueueEmpty(Queue* qp);
#define   _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"
//初始化
//销毁
void QueueInit(Queue* qp)
{
	assert(qp);
	qp->phead = NULL;
	qp->ptail = NULL;
	qp->size = 0;
}
void QueueDestroy(Queue* qp)
{
	assert(qp);
	QNode* cur = qp->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	//释放完空间后需要把phead和ptail置空,不然就为野指针了
	qp->phead = NULL;
	qp->ptail = NULL;
	qp->size = 0;
}
//队尾插入
void QueuePush(Queue* qp, QDatatype x)
{
	assert(qp);

	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(1);
	}
	newnode->next = NULL;
	newnode->val = x;
	//一个节点都没有
	if (qp->phead == NULL)
	{
		qp->phead = qp->ptail = newnode;
	}
	//有一个节点
	else
	{
		qp->ptail->next = newnode;//newnode成为新的尾
		qp->ptail = newnode;
	}
	qp->size++;
}
//对头删除
void QueuePop(Queue* qp)
{
	assert(qp);
	assert(qp->size != 0);
	if (qp->size == 1)//只剩一个节点
	{
		free(qp->phead);
		qp->phead = qp->ptail = NULL;//避免野指针
	}
	else//多个节点
	{
		QNode* next = qp->phead->next;
		free(qp->phead);
		qp->phead = next;
	} 
	qp->size--;
}
	//取头和尾的数据
QDatatype QueueFront(Queue * qp)
{
	assert(qp);
	return qp->phead->val;
}
QDatatype QueueBack(Queue * qp)
{
	assert(qp);
	assert(qp->phead);
	return qp->ptail->val;
}
int QueueSize(Queue* qp)
{
	assert(qp);
	assert(qp->ptail);
	return qp->size;//因为记录了size,所以直接返回size就行,不用遍历
}
bool QueueEmpty(Queue* qp)
{
	assert(qp);
	return qp->size == 0;
}

希望这篇博客对你有所帮助!!!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1677948.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python将两张图片对齐

目录 需要对齐的照片如下&#xff1a; 源码&#xff1a; 结果&#xff1a; 需要对齐的照片如下&#xff1a; 源码&#xff1a; import cv2 import numpy as np from matplotlib import pyplot as plt# 读取两张图片 imgA cv2.imread(./out/out/3.png) imgB cv2.imread(./…

工具:资源包提取

1.提取unity资源包的工具 一定要通过文件夹的方式选择unity文件否则导出来后的资源不完整

锚点组件--支持点击、滚动高亮锚点

实现一个锚点组件&#xff0c;页面滚动时高亮当前位置锚点、点击锚点时跳转到指定冒点位置&#xff0c;同时选中锚点也高亮 效果图 父组件 import ./index.less; import Anchor from ./Anchor; import Content from ./Content;export default function index() {return (<…

rocketmq的流程

生产过程 消费过程 存储 在RocketMQ中&#xff0c;一个Broker的所有Topic的消息都会被写入到同一个CommitLog文件中。 每个队列&#xff08;Queue&#xff09;都有对应的ConsumeQueue文件。 ConsumeQueue每个记录定长&#xff0c;20字节&#xff0c;消息在commitlog中的偏移量…

【软件的安装与基本设置】AD21软件的PCB规则设置

在绘制PCB之前&#xff0c;要进行规则的创建&#xff0c;因为在绘制PCB的过程中&#xff0c;难免会出现很多错误&#xff0c;所以需要先对绘制PCB创建规则&#xff0c;即所有的打孔&#xff0c;走线&#xff0c;铺铜都要基于电气性能规则去设计&#xff0c;等到后期&#xff0c…

[vue] nvm

nvm ls // 看安装的所有node.js的版本nvm list available // 查显示可以安装的所有node.js的版本可以在可选列表里。选择任意版本安装&#xff0c;比如安装16.15.0 执行&#xff1a; nvm install 16.15.0安装好了之后。可以执行&#xff1a; …

云服务器修改端口通常涉及几个步骤

云服务器修改端口通常涉及几个步骤 远程连接并登录到Linux云服务器&#xff1a; 使用SSH工具&#xff08;如PuTTY、SecureCRT等&#xff09;远程连接到云服务器。 输入云服务器的IP地址、用户名和密码&#xff08;或密钥&#xff09;进行登录。 修改SSH配置文件&#xff1a…

智能数据提取:在严格数据治理与安全标准下的实践路径

一、引言 随着信息技术的飞速发展&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;数据量的爆炸式增长和数据格式的多样化&#xff0c;使得传统的数据提取方法变得效率低下且难以满足业务需求。智能数据提取技术应运而生&#xff0c;它通过应用人工智能和机器学…

Unity里的Time

Time and frame rate management Time类&#xff1a; Time script reference page. 一些常见的属性有&#xff1a; Time.time 返回从游戏开始经历的时间.Time.deltaTime 返回从上帧结束到现在经历的时间&#xff0c;和帧率成反比Time.timeScale 控制时间流逝的因子Time.fixe…

一个制剂生产人眼中的精益管理

精益管理&#xff08;Lean Management&#xff09;是一种通过减少浪费和提高价值创造的方法&#xff0c;广泛应用于各个行业中&#xff0c;包括药品制剂生产领域。 本文&#xff0c;以一个多年从事药品制剂生产的人的角度&#xff0c;从优点、功能以及与其他管理方法的比较等方…

交通灯-设计说明书

设计摘要&#xff1a; 本设计基于单片机技术&#xff0c;旨在实现智能化交通信号控制&#xff0c;并具备夜间模式、禁止通行模式、同行模式切换以及车流量监测功能。通过按键S1和S2实现夜间模式和禁止通行模式的切换&#xff0c;确保夜间交通安全和禁止通行的需要。按键S3和S4…

阿里云OSS如果指定某个文件夹给子账户

** 第一步创建子账号 ** 创建完用户不要给任何权限&#xff01; 当前页面切换到认证管理获取AccessKey即可 第二步目录授权 找到对应桶文件目录 上面授权按钮操作 选择添加的子账号账号保存即可&#xff01;

springmvc核心流程

核心流程及配置 核心流程 执行流程 用户发送请求到DispatcherServlet前端控制器&#xff0c;前端控制器收到请求后自己不进行处理&#xff0c;而是委托给其他的解析器进行处理&#xff0c;作为统一访问点&#xff0c;进行全局的流程控制 DispatcherServlet调用HandlerMapping映…

电机完美控制的感觉如何【应用案例】

当电机控制技术成为人体的一部分时&#xff0c;对控制系统的组件尺寸和可靠性要求将极大提高。得益于集成式FOC控制系统组件&#xff0c;第一款具有两个活动关节的义肢得以在短时间内完成—— 赶上在苏黎世举办的全球半机械人奥运会(Cybathlon)。 失去肢体显然会对一个人的生活…

社交媒体的探索者:探寻Facebook的发展历程

在当今数字化时代&#xff0c;社交媒体已经成为了人们日常生活中不可或缺的一部分&#xff0c;而Facebook作为最具影响力的社交平台之一&#xff0c;其发展历程承载着无数的探索与创新。本文将深入探讨Facebook的发展历程&#xff0c;从其创立初期到如今的全球化影响&#xff0…

MySQL深入理解MVCC机制(详解)

深入理解MVCC 1、MVCC定义 MVCC:Multi-Version Concurrency Control&#xff0c;多版本并发控制机制。 在mysql中&#xff0c;为了满足事务的四大特性之一的隔离性&#xff0c;就是当前事务中的查询的数据不受其他事务的增删改操作的影响&#xff0c;因此mysql主要是通过这个…

智能鱼缸-设计说明书

设计摘要&#xff1a; 本论文以STC89C52单片机为核心控制器&#xff0c;构建了一套智能鱼缸系统。该系统由中控部分、输入部分和输出部分组成。中控部分采用STC89C52单片机&#xff0c;负责获取输入部分数据并进行处理&#xff0c;控制输出部分。输入部分包括TDS水质水温检测模…

PyCharm2023 社区版安装 +中文语言包+配置教程+Python环境搭建

一、Python 安装 我们在安装Pycharm之前&#xff0c;首先要先安装Python环境也就是安装Python解释器 因为PyCharm是一个用于编写和调试Python代码的开发工具&#xff0c;而Python解释器是用于解释执行Python代码PyCharm需要依赖Python解释器来执行Python代码&#xff0c;因此…

【Stable Diffusion】 训练方法篇

一、四种模型训练方法简介 Stable Diffusion 有四种训练模型的方法&#xff1a;Textual Inversion、Hypernetwork、LoRA 和 Dreambooth 。它们的训练方法存在一定差异&#xff0c;我们可以通过下面对比来评估使用哪种训练方式最适合你的项目。 如果你知道模型中已经可以产生你…

AI图像生成-调整

一、两张图画风不相似 2、在两张图的共同输出口新添加一个空白正面提示词板块和条件合并板块 二、预处理插件&#xff08;提取人物姿态&#xff09; 1、新建节点-》ControlNet预处理器-》面部与姿态-》Openpose姿态预处理器 2、添加上传图片板块与预览图片板块 3、提取姿态 右…