数据结构——栈和队列

2023-11-03

数据结构——栈和队列

1. 栈

1.1 栈的概念及结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的元素遵循后进先出LIFO(Last In First Out)的原则。

在这里插入图片描述

压栈:栈的插入操作叫做压栈(进栈/入栈),入数据在栈顶。

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

在这里插入图片描述

1.2 栈的实现

栈的实现一般可以使用数组或者链表实现。

链表的实现:每次入栈一个元素,向链表中添加一个节点,出栈一个元素,释放一个节点。通常我们将链表的头部作为栈顶,尾部作为栈底。

在这里插入图片描述

可能会有同学有疑问,为什么将链表的头部作为栈顶,尾部作为栈底呢?

因为栈具有“后进先出”的特点,如果每次在链表的尾部进行插入和删除,就要遍历整个链表来找到尾节点。而在头部进行插入和删除时,只需根据头指针即可找到链表的首元素结点。而无需遍历链表。所以链式栈的出,入栈通过对链表进行头删和头插来实现。

数组的实现:相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。

在这里插入图片描述

typedef int STDataType;
typedef struct Stack
{
    STDataType* a;
    int top; // 栈顶
    int capacity; // 容量
}ST;
// 初始化栈
void StackInit(ST* ps);
// 销毁栈
void StackDestroy(ST* ps);
// 入栈
void StackPush(ST* ps, STDataType x);
// 出栈
void StackPop(ST* ps);
// 获取栈顶元素
STDataType StackTop(ST* ps);
// 获取栈中有效元素个数
int StackSize(ST* ps);
// 检测栈是否为空
bool StackEmpty(ST* ps);

初始化栈

void StackInit(ST* ps)
{
	assert(ps);

	ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->a == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	ps->capacity = 4;
	ps->top = 0;
}

销毁栈

void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

入栈

void StackPush(ST* ps,STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)// 满容量
	{
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps-			>capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

出栈

void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

	ps->top--;
}

获取栈顶元素

STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

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

获取栈中有效元素个数

int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

检测栈是否为空

bool StackEmpty(ST* ps)
{
	assert(ps);
	return (ps->top == 0);
}

2. 队列

2.1 队列的概念及结构

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列遵循先进先出FIFO(First In First Out)的原则。

在这里插入图片描述

入队列:进行插入操作的一端称为队尾;

出队列:进行删除操作的一端称为队头。

2.2 队列的实现

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

在这里插入图片描述

typedef int QDataType;

typedef struct QueueNode
{
	QDataType data;
	struct Queue* next;
}QNode;

typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

// 初始化队列
void QueueInit(Queue* pq);
// 销毁队列
void QueueDestroy(Queue* pq);
// 队尾入队列
void QueuePush(Queue* pq,QDataType x);
// 队头出队列
void QueuePop(Queue* pq);
// 获取队列头部元素
QDataType QueueFront(Queue* pq);
// 获取队列尾部元素
QDataType QueueBack(Queue* pq);
// 检测队列是否为空
bool QueueEmpty(Queue* pq);
// 获取队列中有效元素个数
int QueueSize(Queue* pq);

初始化队列

void QueueInit(Queue* pq)
{
	assert(pq);

	pq->head = NULL;
	pq->tail = NULL;
	pq->size = 0;
}

销毁队列

void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur != NULL)
	{
		QNode* del = cur;
		cur = cur->next;
		free(del);
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

队尾入队列

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}

队头出队列

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* del = pq->head;
		pq->head = pq->head->next;
		free(del);
	}
	pq->size--;
}

获取队列头部元素

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

获取队列尾部元素

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

检测队列是否为空

bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL && pq->tail == NULL;
}

获取队列中有效元素个数

int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构——栈和队列 的相关文章

  • D (1173) : A DS二叉树_合并二叉树

    文章目录 一 题目描述 二 输入与输出 1 输入 2 输出 三 参考代码 一 题目描述 给定两个二叉树 输出这两个二叉树合并后形成的二叉树 依次输出前序遍历 中序遍历 后序遍历 二 输入与输出 1 输入 第一行输入t 表示有t个测试样例 第
  • E (1052) : DS树--带权路径和

    文章目录 一 题目描述 二 输入与输出 1 输入 2 输出 三 参考代码 一 题目描述 计算一棵二叉树的带权路径总和 即求赫夫曼树的带权路径和 已知一棵二叉树的叶子权值 该二叉树的带权路径和APL等于叶子权值乘以根节点到叶子的分支数 然后求
  • 不会做的题汇总

    摘苹果 题目描述 小红来到苹果园 帮园长摘苹果 园长请小红把摘完的苹果的最小的那个去掉 如果有 多个最小的苹果 那么都要去掉 剩余的苹果算一下平均一个苹果有多重 平均重 量请保留1位小数 输入 输入有2行 第一行 一个整数n代表小红摘的n个
  • c 关于数组几个查序程序

    1 查询某元素是否在数组中 int main void char i 10 2 1 7 2 10 5 2 0 1 4 10 10 1 3 1 0 8 char z 10 1 2 3 4 1 4 6 8 0 9 int zz 0 标志位 0
  • DS八大排序之冒泡排序和快速排序

    前言 前两期我们已经对 插入排序 直接插入排序和希尔排序 和 选择排序 直接选择排序和堆排序 进行了详细的介绍 这一期我们再来详细介绍一组排序 交换排序 即耳熟能详的冒泡排序和赫赫有名的快速排序 本期内容介绍 冒泡排序 快速排序 Hoare
  • 每日一练2023.12.17——大笨钟的心情【PTA】

    题目链接 L1 077 大笨钟的心情 题目要求 有网友问 未来还会有更多大笨钟题吗 笨钟回复说 看心情 本题就请你替大笨钟写一个程序 根据心情自动输出回答 输入格式 输入在一行中给出 24 个 0 100 区间内的整数 依次代表大笨钟在一天
  • 剑指 Offer(第2版)面试题 35:复杂链表的复制

    剑指 Offer 第2版 面试题 35 复杂链表的复制 剑指 Offer 第2版 面试题 35 复杂链表的复制 解法1 模拟 剑指 Offer 第2版 面试题 35 复杂链表的复制 题目来源 48 复杂链表的复刻 解法1 模拟 算法 复制原
  • LeetCode326. Power of Three

    文章目录 一 题目 二 题解 一 题目 Given an integer n return true if it is a power of three Otherwise return false An integer n is a po
  • 深度学习目标检测全连接层什么意思

    在深度学习目标检测中 通常我们使用卷积神经网络 Convolutional Neural Network CNN 进行特征提取 CNN 的主要结构包括卷积层和池化层 用于从输入图像中提取特征 然而 为了最终输出目标的类别和位置信息 通常在网
  • 华为OD机试 C++【最大载货量】

    描述 在火车站旁的货运站 小明负责调度2K辆中转车 其中K辆用于干货 K辆用于湿货 每批到站的货物来自不同的供货商 需要按照顺序装入中转车 注意 一个供货商的货物只能装在一辆车上 不能分开 但是 一辆车可以放多个供货商的货物 问题是 要让所
  • 面试150-13(Leetcode238除自身以外数组的乘积)

    代码 class Solution public int productExceptSelf int nums int n nums length int res new int n int product 1 int zerocnt 0
  • 数组对象排序 (arr.sort())

    前端面试题库 面试必备 推荐 地址 前端面试题库 对象排序 arr sort 描述 方法sort 将在原数组上对 数组元素 进行排序 即排序时不创建新的数组副本 如果想按照别的顺序进行排序 就必须提供比较函数 该函数要比较两个值 然后返回一
  • 《LeetCode力扣练习》代码随想录——双指针法(反转链表---Java)

    LeetCode力扣练习 代码随想录 双指针法 反转链表 Java 刷题思路来源于 代码随想录 206 反转链表 双指针 Definition for singly linked list public class ListNode int
  • 冒泡排序/选择排序/插入排序/快速排序/归并排序/桶排序/堆排序/希尔排序/计数排序/基数排序/二分查找/广度优先搜索/深度优先搜索

    排序算法 冒泡排序 Bubble Sort 通过重复地比较相邻的元素并交换它们 使得最大 或最小 的元素逐渐移动到列表的一端 从而实现排序 选择排序 Selection Sort 在未排序的部分中 选择最小 或最大 的元素 并将其放置在已排
  • Leetcode 45 跳跃游戏 II

    题意理解 给定一个长度为 n 的 0 索引 整数数组 nums 初始位置为 nums 0 每个元素 nums i 表示从索引 i 向前跳转的最大长度 还是从初始坐标i 0的位置到达最后一个元素 但是问题不是能不能跳到 而是 最少几步能跳到最
  • 冒泡排序/选择排序/插入排序/快速排序/归并排序/桶排序/堆排序/希尔排序/计数排序/基数排序/二分查找/广度优先搜索/深度优先搜索

    排序算法 冒泡排序 Bubble Sort 通过重复地比较相邻的元素并交换它们 使得最大 或最小 的元素逐渐移动到列表的一端 从而实现排序 选择排序 Selection Sort 在未排序的部分中 选择最小 或最大 的元素 并将其放置在已排
  • 【LeetCode:114. 二叉树展开为链表 | 二叉树 + 递归】

    算法题 算法刷题专栏 面试必备算法 面试高频算法 越难的东西 越要努力坚持 因为它具有很高的价值 算法就是这样 作者简介 硕风和炜 CSDN Java领域新星创作者 保研 国家奖学金 高中学习JAVA 大学完善JAVA开发技术栈 面试刷题
  • 排序:计数排序

    一 概念 计数排序是非比较排序 是对哈希直接定址法的变形应用 二 思想 利用数组统计相同数据出现的次数 例如整型数据m出现n次 就在数组m位置记录数据为n 最后从头遍历数组打印数据即可 通俗来讲就是 数组下标即为数据 下标所指位置的值即为数
  • 「优选算法刷题」:快乐数

    一 题目 编写一个算法来判断一个数 n 是不是快乐数 快乐数 定义为 对于一个正整数 每一次将该数替换为它每个位置上的数字的平方和 然后重复这个过程直到这个数变为 1 也可能是 无限循环 但始终变不到 1 如果这个过程 结果为 1 那么这个
  • 最大流-Dinic算法,原理详解,四大优化,详细代码

    文章目录 零 前言 一 概念回顾 可略过 1 1流网络 1 2流 1 3最大流 1 4残留网络 1 5增广路

随机推荐

  • windows 系统 cmake 编译 python 使用 boost 库的问题

    使用 cmake 编译跨平台的开源框架 遇到 cmake 编译出错 主要报错是 FindBoost cmake 通过各种输入日志 message 发现有几个地方需要注意 现记录下来 需要修改成自己的boost版本 set RDK BOOST
  • 华为OD机试真题 Java 实现【分界线】【2023Q1 100分】

    一 题目描述 电视剧 分界线 里面有一个片段 男主为了向警察透露案件细节 且不暴露自己 于是将报刊上的字剪切下来 剪拼成匿名信 现在有一名举报人 希望借鉴这种手段 使用英文报刊完成举报操作 但为了增加文章的混淆度 只需满足每个单词中字母数量
  • API 网关基础

    目录 一 网关概述 二 网关提供的功能 三 常见网关系统 3 1 Netflix Zuul 3 2 Spring Cloud Gateway 3 3 Kong 3 4 APISIX 3 5 Shenyu 一 网关概述 API网关是一个服务器
  • [微信官方文档] 小程序-错误码信息与解决方案表

    错误码信息与解决方案表 错误码是通过binderror回调获取到的错误信息 代码 异常情况 理由 解决方案 1000 后端错误调用失败 该项错误不是开发者的异常情况 一般情况下忽略一段时间即可恢复 1001 参数错误 使用方法错误 可以前往
  • linux:docker /bin/bash作用

    参考 docker run it centos bin bash 后面的 bin bash的作用
  • 【整理一】

    1 说说你对react的理解 有哪些特性 React是一个前端js框架 React高效灵活 声明式设计 使用简单 组件式开发 提高代码的复用率 单向的数据绑定比双向的数据绑定更加安全 2 说说Real diff算法是怎么运作的 1 Diff
  • CrackQL:一款功能强大的图形化密码爆破和模糊测试工具

    关于CrackQL CrackQL是一款功能强大的图形化密码爆破和模糊测试工具 在该工具的帮助下 广大研究人员可以针对密码安全和应用程序安全进行渗透测试 除此之外 CrackQL同时也是一款通用的GraphQL渗透测试工具 它可以控制速率限
  • 积分图(三) - Boxfilter 的实现过程分析

    积分图 三 Boxfilter 的实现过程分析 Boxfilter 快速计算 它可以使复杂度为O MN 的求和 求方差等运算降低到O 1 或近似于O 1 的复杂度 它的缺点是不支持多尺度 Boxfilter 的原理有点类似 Integral
  • 大学应让我们相信各种可能性

    记得刚来学校的时候 导员们便告诉我们今年的学长学姐们找的工作工资有多高 他们保研保上了多么好的学校 有多少人竞赛怎么样怎么样 于是一开始 我们心中的价值取向便成了这些 而我们竟然还很激动 因为我们将来或许也能取得同样的工资 同样的成就 其实
  • python过期了怎么恢复_pycharm过期30天没法用了怎么办?

    用cleanmyMac查看 右键在finder中显示可以找到文件位置 image png Users xxx Library Saved Application State com jetbrains pycharm savedState
  • STL容器之deque

    文章目录 deque容器简介 deque的操作 deque容器简介 deque是 double ended queue 的缩写 和vector一样都是STL的容器 deque是双端数组 而vector是单端的 deque在接口上和vecto
  • TypeScript中的联合类型、类型别名、接口、类型断言

    一 联合类型 在TypeScript中 联合类型 Union Types 是指用 符号将多个类型组合成一个的类型 这种类型可以包含不同的类型 例如字符串 数字或对象 这些不同类型的值可以赋值给联合类型的变量 而在使用这个变量时 需要对不同类
  • Crazy Search 【POJ - 1200】【哈希】

    题目链接 题意 给定一个字符串 其中含有不同的字母数量为m 现在求这个字符串中有多少个长度为n且长的互不相同的字符子串 举个例子 n 3 m 4 字符串 daababac 长度为3的不同的子串分别是 daa aab aba bab bac
  • Linux基线检查与安全加固

    安全加固 Linux安全加固 账户管理 一 口令锁定策略 检查操作步骤 查看配置文件 more etc pam d password auth 查看是否存在如下内容 auth required pam tally2 so deny 5 on
  • SVM支持向量机的多输入单输出预测模型

    多输入单输出 使用SVM做预测的时候 涉及到数据处理 这里强调一下 其它预测算法也适用 我们经常将收集数据集进行归一化 标准化 其实 只需要对部分数据进行归一化即可 归一化的目的是将输入向量中的各属性之间的数量级拉近 如果量级相差过大会影响
  • Java经典面试解析:服务器卡顿、CPU飙升、接口负载剧增

    线上服务器CPU飙升 如何定位到Java代码 解决这个问题的关键是要找到Java代码的位置 下面分享一下排查思路 以CentOS为例 总结为4步 第1步 使用top命令找到占用CPU高的进程 第2步 使用ps mp命令找到进程下占用CPU高
  • ui设计移动端字体适配_手机端页面UI设计尺寸和字体大小规范

    UI设计师在初涉移动端设计和开发的时候 基本都会面临一个令人十分苦恼的问题那就是移动端页面UI设计尺寸标准和字体规范 今天奇酷学院整理了一些关于手机端页面UI设计尺寸和字体大小规范问题 希望对UI设计师设计移动端页面的时候有一些帮助 一 P
  • js实现框选截屏功能

    实现的思路大概就是 先将dom转化为canvas画布 再对canvas进行裁切 然后通过canvas api生成图片 这里用到了一个库html2canvas 效果如图 首先实现框选效果 const mousedownEvent e gt m
  • java 订单审核 加锁_日常小记:订单添加锁机制

    考虑情况 java是个多线程机制 多线程是一把双刃剑 一旦设计到多个线程操作共享资源的情况下 处理不好就会出现线程安全问题 线程安全性可能是非常复杂的 在沒有充足的同步情况下 多个线程执行顺序是不好操作的 同步和异步 同步就是一件事 一件事
  • 数据结构——栈和队列

    数据结构 栈和队列 数据结构 栈和队列 数据结构 栈和队列 1 栈 1 1 栈的概念及结构 1 2 栈的实现 2 队列 2 1 队列的概念及结构 2 2 队列的实现 1 栈 1 1 栈的概念及结构 栈 一种特殊的线性表 其只允许在固定的一端