栈和队列篇

news2024/11/23 15:15:19

目录

一、栈

1.栈的概念及结构

1.1栈的概念

1.2栈的结构示意图

2.栈的实现

2.1支持动态增长的栈的结构

2.2压栈(入栈)

2.3出栈

2.4支持动态增长的栈的代码实现

二、队列

1.队列的概念及结构

1.1队列的概念

1.2队列的结构示意图

2.队列的实现

2.1队列的结构

2.2队尾入队列

2.3队头出队列

2.4队列的代码实现

一、栈

1.栈的概念及结构

1.1栈的概念

        栈是一种特殊的线性表。栈只允许在固定的一端进行插入和删除数据的操作,栈的插入操作叫做压栈(进栈),栈的删除操作叫做出栈,进行数据插入和删除操作的一端叫做栈顶,另一端为栈底。栈中的元素遵循先进后出的原则。

1.2栈的结构示意图

2.栈的实现

        栈一般分为静态栈和支持动态增长的栈,静态栈由于栈的空间大小固定不具实用性,所以我们只针对支持动态增长的栈进行代码实现:

2.1支持动态增长的栈的结构

        栈的实现一般使用数组形式来实现,支持动态增长的栈即开辟一个动态数组a用来存储数据,当栈的容量满了之后方便扩容。

// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;		// 栈顶
	int capacity;  // 容量 
}Stack;

2.2压栈(入栈)

        每次压栈首先检查栈的容量是否已满,再决定是否需要扩容,压栈的元素变为新的栈顶

// 入栈 
void StackPush(Stack* ps, STDataType data)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 5 : (ps->capacity) * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc:");
			return;
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
	ps->a[ps->top] = data;
	ps->top++;
}

2.3出栈

        出栈后新的栈顶变为出栈前的栈顶的前一个元素

// 出栈 
void StackPop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	ps->top--;
}

2.4支持动态增长的栈的代码实现

#pragma once
#include<assert.h>
#include<stdlib.h>
#include<stdio.h>

// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;		// 栈顶
	int capacity;  // 容量 
}Stack;

// 初始化栈 
void StackInit(Stack* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;//top指向栈顶的下一个位置,对top的操作需要是:先使用后++
	ps->capacity = 0;
}

// 入栈 
void StackPush(Stack* ps, STDataType data)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 5 : (ps->capacity) * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc:");
			return;
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
	ps->a[ps->top] = data;
	ps->top++;
}

// 出栈 
void StackPop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	ps->top--;
}

// 获取栈顶元素 
STDataType StackTop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	return ps->a[ps->top - 1];
}

// 获取栈中有效元素个数 
int StackSize(Stack* ps)
{
	assert(ps);
	return ps->top;
}

// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps)
{
	assert(ps);
	return ps->top == 0;
}

// 销毁栈 
void StackDestroy(Stack* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

二、队列

1.队列的概念及结构

1.1队列的概念

        不同于栈的概念,队列只允许在其一端进行插入数据操作,在另一端进行删除数据操作。进行插入数据操作的一端是队尾,进行删除数据操作的一端是队头。队列是一种特殊的线性表,遵循先进先出的原则。

1.2队列的结构示意图

2.队列的实现

2.1队列的结构

        队列的实现一般使用链表的结构更优:

代码:

// 队列成员节点结构
typedef int QDataType;
typedef struct QListNode
{
	struct QListNode* next;
	QDataType data;
}QNode;

// 队列的结构 
typedef struct Queue
{
	QNode* front;
	QNode* rear;
	int size;
}Queue;

简图:

2.2队尾入队列

代码:

// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	
	QNode* NewNode = (QNode*)malloc(sizeof(QNode));
	if (NewNode == NULL)
	{
		perror("malloc:");
		return;
	}
	NewNode->data = data;
	NewNode->next = NULL;
	if (q->size == 0)
	{
		q->front = q->rear = NewNode;
	}
	else
	{
		q->rear->next = NewNode;
		q->rear = q->rear->next;
	}
	q->size++;
}

简图:

2.3队头出队列

代码:

// 队头出队列 
void QueuePop(Queue* q)
{
	assert(q);
	//assert(!QueueEmpty(q));
	if (q->front ==q->rear)
	{
		if (q->front == NULL)
		{
			return;
		}
		else
		{
			free(q->front);
			q->front = q->rear = NULL;
		}
	}
	else
	{
		QNode* Tmp = q->front;
		q->front = Tmp->next;
		free(Tmp);
		Tmp = NULL;
	}
	q->size--;
}

简图:

2.4队列的代码实现

#pragma once
#include<assert.h>
#include<stdlib.h>
#include<stdio.h>

// 链式结构:表示队列成员节点
typedef int QDataType;
typedef struct QListNode
{
	struct QListNode* next;
	QDataType data;
}QNode;

// 队列的结构 
typedef struct Queue
{
	QNode* front;
	QNode* rear;
	int size;
}Queue;

// 初始化队列 
void QueueInit(Queue* q)
{
	assert(q);
	q->front = q->rear = NULL;
	q->size = 0;
}

// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	
	QNode* NewNode = (QNode*)malloc(sizeof(QNode));
	if (NewNode == NULL)
	{
		perror("malloc:");
		return;
	}
	NewNode->data = data;
	NewNode->next = NULL;
	if (q->size == 0)
	{
		q->front = q->rear = NewNode;
	}
	else
	{
		q->rear->next = NewNode;
		q->rear = q->rear->next;
	}
	q->size++;
}

// 队头出队列 
void QueuePop(Queue* q)
{
	assert(q);
	//assert(!QueueEmpty(q));
	if (q->front ==q->rear)
	{
		if (q->front == NULL)
		{
			return;
		}
		else
		{
			free(q->front);
			q->front = q->rear = NULL;
		}
	}
	else
	{
		QNode* Tmp = q->front;
		q->front = Tmp->next;
		free(Tmp);
		Tmp = NULL;
	}
	q->size--;
}

// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));
	return q->front->data;
}

// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));
	return q->rear->data;
}

// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{
	assert(q);
	return q->size;
}

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{
	assert(q);
	return q->size == 0 ? 1 : 0;
}

// 销毁队列 
void QueueDestroy(Queue* q)
{
	assert(q);
    while(!QueueEmpty(q))
    {
        QueuePop(q);
    }
}

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

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

相关文章

指针(一)------指针概念+指针类型+野指针+指针运算+二级指针

&#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C语言 &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &#x1f339;&#x1f339;&#x1f339;关注我带你学习编程知识 指针&#xff08;一&#xff09; 指针是什么指针…

剪枝基础与实战(5): 剪枝代码详解

对模型进行剪枝,我们只对有参数的层进行剪枝,我们基于BatchNorm2d对通道重要度 γ \gamma γ参数进行稀释训练。对BatchNorm2d及它的前后层也需要进行剪枝。主要针对有参数的层:Conv2d、BatchNorm2d、Linear。但是我们不会对Pool2d 层进行剪枝,因为Pool2d只用来做下采样,没…

MacApp自动化测试之常用工具简介

自动化测试在国内主要以单元测试、API测试、WebUI测试为主&#xff0c;对于MacApp测试却鲜有涉及。但2021年统计MacBook市场占有率接近10%&#xff0c;相比前一年市场占有率提升了26%&#xff0c;可见发展势头非常不错。 与此MacBook上的应用程序MacApp也在有序地发展着&#…

ESP32C3 LuatOS RC522②写入字符串

编写了字符串转16进制表函数 -- 将字符串转换为十六进制表 local function stringToHexTable(str)local hexTable {}local maxLength 16 -- 最大长度为16个元素-- 将字符串转换为十六进制for i 1, #str doif i > maxLength thenbreakendlocal hex string.format("…

解密Spring事务生效的内部机制

声明式事务和编程式事务对比&#xff1a; 声明式事务&#xff1a; 使用注解或XML配置的方式&#xff0c;在代码中声明事务的属性和行为。通过AOP和代理模式实现&#xff0c;将事务管理与业务逻辑代码解耦。适用于大多数情况&#xff0c;简化了代码&#xff0c;提高了可维护性和…

9.2作业

QT实现闹钟 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QTimerEvent> #include<QDateTime> #include<QLineEdit> #include<QLabel> #include<QPushButton> #include <QTextToSpeech> QT_BEGIN_NAMES…

sqlserver 自定义函数汉字转拼音或首字母

作用&#xff1a; 将汉字生成为全拼音或者首字母&#xff0c;示例 执行自定义函数&#xff0c;将汉字转成对应的首字母 执行自定义函数&#xff0c;将汉字转成全拼音 自定义教程&#xff1a; 一&#xff0c;只取汉字的首字母 代码如下&#xff1a; 执行下面sql 就自定义函数了…

骨传导耳机对人有伤害吗?骨传导耳机和入耳式耳机的区别是什么?

如果是正确的使用骨传导耳机&#xff0c;是不会对人体造成伤害的&#xff0c;在人的耳蜗内有一种细胞很重要&#xff0c;叫做内毛细胞&#xff0c;主要的工作就是负责识别声音&#xff0c;我们能听到声音跟它密不可分&#xff0c;并且内毛细胞在收到损害后是不会自我修复的&…

go Session的实现(一)

〇、前言 众所周知&#xff0c;http协议是无状态的&#xff0c;这对于服务器确认是哪一个客户端在发请求是不可能的&#xff0c;因此为了能确认到&#xff0c;通常方法是让客户端发送请求时带上身份信息。容易想到的方法就是客户端在提交信息时&#xff0c;带上自己的账户和密…

论文阅读_扩散模型_DM

英文名称: Deep Unsupervised Learning using Nonequilibrium Thermodynamics 中文名称: 使用非平衡热力学原理的深度无监督学习 论文地址: http://arxiv.org/abs/1503.03585 代码地址: https://github.com/Sohl-Dickstein/Diffusion-Probabilistic-Models 时间: 2015-11-18 作…

Mqtt学习笔记--交叉编译移植(1)

简述 Mqtt目前在物联网行业的应用比较多&#xff0c;mqtt属于应用层的一个中间件&#xff0c;这个中间件实现消息的订阅发布机制。网上介绍Mqtt的实现原来的比较多&#xff0c;这里不细介绍。 其实在我们之前的产品中&#xff0c;自己也开发的有类似的中间件&#xff0c;除了具…

第 3 章 栈和队列 (算法 3.5,汉诺塔问题递归解法)

1. 背景说明 假设有 3 个分别命名为 X、Y 和 Z 的塔座&#xff0c;在塔座 X 上插有 n 个直径大小各不相同、依小到大编号为 1, 2&#xff0c;…&#xff0c;n 的圆盘。现要求将 X 轴上的 n 个圆 盘移至塔座 Z 上并仍按同样顺序叠排&#xff0c;圆盘移动时必须遵循下列规则&…

面试官问我MySQL和MariaDB的联系和区别,这我能不知道?

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…

重装Windows10系统

以前清理电脑我一般是重置电脑的&#xff0c;但是重置电脑会清理C盘&#xff0c;新系统又遗留有以前的系统文件&#xff0c;导致后面配置环境遇到了棘手的问题&#xff0c;所以我打算重装系统。 第一次重装windows10系统&#xff0c;踩了很多坑&#xff0c;搞了两天才配回原来的…

Intel 80386运行模式

Intel 80386运行模式 一般CPU只有一种运行模式&#xff0c;能够支持多个程序在各自独立的内存空间中并发执行&#xff0c; 且有用户特权级和内核特权级的区分&#xff0c;让一般应用不能破坏操作系统内核和执行特权指令。 80386处理器有四种运行模式&#xff1a;实模式、保护模…

Day53|动态规划part14: 1143.最长公共子序列、1035. 不相交的线、53. 最大子序和

1143. 最长公共子序列 leetcode链接&#xff1a;力扣题目链接 视频链接&#xff1a;动态规划子序列问题经典题目 | LeetCode&#xff1a;1143.最长公共子序列 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。 如果不存在 公共子序列 …

在工具提示中使用自绘修改字体

在上一篇文章中&#xff0c;我们学习了如何在应用程序中添加工具提示。在之前的例子代码中&#xff0c;我们通过简单地为创建的工具提示设置了目标字体&#xff0c;这种方法很简单&#xff0c;因为自始至终&#xff0c;我们都只创建了一个工具提示。 但是&#xff0c;如果在应…

【数据结构】2015统考真题 6

题目描述 【2015统考真题】求下面的带权图的最小&#xff08;代价&#xff09;生成树时&#xff0c;可能是Kruskal算法第2次选中但不是Prim算法&#xff08;从v4开始&#xff09;第2次选中的边是&#xff08;C&#xff09; A. (V1, V3) B. (V1, V4) C. (V2, V3) D. (V3, V4) …

亚马逊,eBay,速卖通买家账号是如何实现高权重,高存活率的

现在测评&#xff0c;补单机构越来越多&#xff0c;看似寻常的便捷渠道也潜藏着很大的风险&#xff0c;尤其是当大量机器代替人工、各种质量参差不齐的测评机构被曝光&#xff0c;跨境卖家“踩坑遇骗”的情况也就屡屡出现。很多卖家都选择自己注册买家账号&#xff0c;自己做测…

YOKOGAWA CP461-50处理器模块

数据处理能力&#xff1a; CP461-50 处理器模块具有强大的数据处理能力&#xff0c;用于执行各种控制和数据处理任务。 多通道支持&#xff1a; 该模块通常支持多通道输入和输出&#xff0c;允许与多个传感器和执行器进行通信。 通信接口&#xff1a; CP461-50 处理器模块通常…