初步认识栈和队列

news2024/11/18 14:32:57

Hello,everyone,今天小编讲解栈和队列的知识!!!

1.栈

1.1栈的概念及结构

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

1.2栈的实现

栈的实现一般可以使用 数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。

4989397040924c16ae4cee9cde928b58.pngceeed439a06943b3b425c53438865c60.png1.2.1 头文件的建立

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef  int  datatype;
//这里选用动态数组实现栈,单链表也可以
typedef struct stack {
	datatype* a;
	int top;//栈顶
	int capacity;
}ST;
//栈的初始化和销毁
void STInit(ST* pst);
void STDestory(ST* pst);
//入栈和出栈
void STPush(ST* pst,datatype x);
void STPop(ST* pst);
//获取栈顶数据
datatype STTop(ST* pst);
//判空
bool STEmpty(ST* pst);
//栈的数据个数
int STSize(ST* pst);

1.2.2 函数的实现

#define _CRT_SECURE_NO_WARNINGS
#include "Stack.h"
//栈的初始化和销毁
void STInit(ST* pst){
	assert(pst);
	pst->a = NULL;
	//top指向栈顶数据的下一个位置,可以理解为下标
	pst->top = 0;
	//top指向指向栈顶数据,可以理解成栈的数据个数
	//pst->top=-1;
	pst->capacity = 0;
}
void STDestory(ST* pst) {
	assert(pst);
	free(pst);
	pst->a = NULL;
	pst->top = pst->capacity = 0;
}
//容量检查
void Checkcapacity(ST* pst) {
	assert(pst);
	if (pst->top == pst->capacity) {
		int newcapacity = pst->capacity==0?4:pst->capacity * 2;
		datatype* temp = (datatype*)realloc(pst->a, newcapacity * sizeof(datatype));
		if (temp == NULL) {
			perror("relloc fail");
			return;
		}
		pst->a = temp;
		pst->capacity = newcapacity;
	}
}
//入栈和出栈
void STPush(ST* pst, datatype x) {
	assert(pst);
	Checkcapacity(pst);
	pst->a[pst->top] = x;
	pst->top++;
}
void STPop(ST* pst) {
	assert(pst);
	assert(pst->top>0);
	pst->top--;
}
//获取栈顶数据
datatype STTop(ST* pst) {
	assert(pst);
	assert(pst->top > 0);
	return pst->a[pst->top-1];
}
//判空
bool STEmpty(ST* pst) {
	assert(pst);
	return pst->top == 0;//表达式判断
}
//栈的数据个数
int STSize(ST* pst) {
	assert(pst);
	return pst->top;
}

1.2.3 测试文件

#define _CRT_SECURE_NO_WARNINGS
#include "Stack.h"
int main() {
	ST s;
	STInit(&s);
	STPush(&s, 1);
	STPush(&s, 2);
	STPush(&s, 3);
	STPush(&s, 4);
	STPush(&s, 5);
	printf("%d\n", STTop(&s));
	STPop(&s);
	//STPop(&s);
	printf("%d\n", STTop(&s));
	while (!STEmpty(&s)) {
		printf("%d ", STTop(&s));
		STPop(&s);
	}
	STDestory(&s);
	return 0;
}

2.队列

2.1队列的概念及结构

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out)
入队列:进行插入操作的一端称为 队尾
出队列:进行删除操作的一端称为 队头
a3d78288b96b48a6af897e6024c62981.png

2.2队列的实现

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

2.2.1 头文件的建立

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
typedef int Qdatatype;
//链式结构表示队列
typedef struct QueueNode {
	struct QueueNode* next;
	Qdatatype x;
}Node;
//定义结构体表示队头队尾,后续传参改变队列也很方便,不用传二级指针。
typedef struct Queue {
	Node* head;
	Node* tail;
	int size;
}Queue;
// 初始化队列
void QueueInit(Queue* q);

// 队尾入队列
void QueuePush(Queue* q, Qdatatype data);

// 队头出队列
void QueuePop(Queue* q);

// 获取队列头部元素
Qdatatype QueueFront(Queue* q);

// 获取队列队尾元素
Qdatatype QueueBack(Queue* q);

// 获取队列中有效元素个数
int QueueSize(Queue* q);

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q);

// 销毁队列
void QueueDestroy(Queue* q);

2.2.2  函数的实现

#define _CRT_SECURE_NO_WARNINGS
#include "Queue.h"
void QueueInit(Queue* q) {
	assert(q);
	q->head = NULL;
	q->tail = NULL;
	q->size = 0;
}
// 队尾入队列
void QueuePush(Queue* q, Qdatatype data) {
	assert(q);
	Node* newnode = (Node*)malloc(sizeof(Node));
	if (newnode == NULL) {
		perror("malloc fail");
		return;
	}
	newnode->next = NULL;
	newnode->x = data;
	if (q->tail ==NULL) {
		q->head = q->tail = newnode;
	}
	else {
		q->tail->next = newnode;
		q->tail = newnode;
	}
	q->size++;
}
// 队头出队列
void QueuePop(Queue* q) {
	assert(q);
	assert(q->size != 0);
	//一个节点
	if (q->head->next == NULL) {
		free(q->head);
		q->head = q->tail = NULL;
	}
	else {
		Node* next = q->head->next;
		free(q->head);
		q->head = next;
	}
	q->size--;
}
// 获取队列头部元素
Qdatatype QueueFront(Queue* q) {
	assert(q);
	assert(q->head);
	return q->head->x;
}
// 获取队列队尾元素
Qdatatype QueueBack(Queue* q) {
	assert(q);
	assert(q->tail);
	return q->tail->x;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q) {
	assert(q);
	return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q) {
	assert(q);
	return q->size == 0;//为0,返回1,不为0,返回0;
}
// 销毁队列
void QueueDestroy(Queue* q) {
	assert(q);
	Node* qcur = q->head;
	while (qcur) {
		Node* next = qcur->next;
		free(qcur);
		qcur = next;
	}
	q->head = q->tail = NULL;
	q->size = 0;
}

2.2.3  测试文件

#define _CRT_SECURE_NO_WARNINGS
#include "Queue.h"
int main() {
	Queue p;
	QueueInit(&p);
	QueuePush(&p,1);
	QueuePush(&p,2);
	printf("%d\n", QueueFront(&p));
	QueuePush(&p, 3);
	QueuePush(&p, 4);
	printf("%d\n",QueueBack(&p));
	QueuePop(&p);
	printf("%d\n", QueueFront(&p));
	while (!QueueEmpty(&p))
	{
		printf("%d ", QueueFront(&p));
		QueuePop(&p);
	}
	printf("\n");
	return 0;
}
另外扩展了解一下,实际中我们有时还会使用一种队列叫循环队列。如操作系统讲解生产者消费者模型时可以就会使用循环队列。环形队列可以使用数组实现,也可以使用循环链表实现。
 
adf81511000b4a73a28cca90fa8f2109.png
 
今天内容讲解结束,下次小编将讲解栈和队列的相关习题。
希望各位友友留下三连和评论!!!
 
 
 
 
 
 

 

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

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

相关文章

Mysql 找出未提交事务的SQL及死锁

未提交事务&#xff1a; 通过查看information_schema.INNODB_TRX视图,您可以了解当前系统中正在运行的事务情况,从而进行问题排查和性能优化。 SELECT * FROM information_schema.innodb_trx; 通过trx_state为RUNNIG,trx_started判断是否有一直RUNNING的事务。 如果有未提交…

Linux修炼之路之冯系结构,操作系统

目录 一&#xff1a;冯诺依曼体系结构 1.五大组件 2.存储器存在的意义 3.几个问题 二&#xff1a;操作系统 接下来的日子会顺顺利利&#xff0c;万事胜意&#xff0c;生活明朗-----------林辞忧 一&#xff1a;冯诺依曼体系结构 我们当代的计算机的基本构成都是由冯诺依曼…

【深度学习】第1章

概论: 机器学习是对研究问题进行模型假设,利用计算机从训练数据中学习得到模型参数,并最终对数据进行预测和分析,其基础主要是归纳和统计。 深度学习是一种实现机器学习的技术,是机器学习重要的分支。其源于人工神经网络的研究。深度学习的模型结构是一种含多隐层的神经…

MySQL增删查改进阶

数据库约束表的关系增删查改 目录 一.数据库约束类型 NOT NULL约束类型 UNIQUE 唯一约束 DEFAULT 默认值约束 PRIMARY KEY&#xff1a;主键约束 FOREIGN KEY :W外键约束 二&#xff0c;查询 count&#xff08;&#xff09;两种用法 sum&#xff0c;avg&#xff0c;max…

python文件处理之os模块和shutil模块

目录 1.os模块 os.path.exists(path)&#xff1a;文件或者目录存在与否判断 os.path.isfile(path)&#xff1a;判断是否是文件 os.path.isdir(path)&#xff1a;判断是否是文件夹 os.remove(path)&#xff1a;尝试删除文件 os.rmdir(path)&#xff1a;尝试删除目录 os.m…

【设计模式】——装饰模式(包装器模式)

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

行为型设计模式之模板模式

文章目录 概述原理结构图实现 小结 概述 模板方法模式(template method pattern)原始定义是&#xff1a;在操作中定义算法的框架&#xff0c;将一些步骤推迟到子类中。模板方法让子类在不改变算法结构的情况下重新定义算法的某些步骤。 模板方法中的算法可以理解为广义上的业…

Linux驱动(3)- LInux USB驱动层次

在Linux系统中&#xff0c;提供了主机侧和设备侧USB驱动框架。 从主机侧&#xff0c;需要编写USB驱动包括主机控制器驱动&#xff0c;设备驱动两类&#xff0c;USB 主机控制驱动程序控制插入其中的USB设备。 USB设备驱动程序控制该设备如何作为从设备与主机进行通信。 1.主机…

文件夹打开出错?这里有你需要的数据恢复与预防指南

在日常使用电脑时&#xff0c;我们有时会遇到文件夹打开出错的情况。当你尝试访问某个文件夹时&#xff0c;系统可能会弹出一个错误提示&#xff0c;告诉你无法打开该文件夹。这种情况不仅会影响我们的工作效率&#xff0c;还可能导致重要数据的丢失。接下来&#xff0c;我们将…

Flutter-自定义折叠流布局实现

需求 在 Flutter 开发中&#xff0c;常常需要实现自定义布局以满足不同的需求。本文将介绍如何通过自定义组件实现一个折叠流布局&#xff0c;该组件能够显示一系列标签&#xff0c;并且在内容超出一定行数时&#xff0c;可以展开和收起。 效果 该折叠流布局可以显示一组标签…

ROCm上运行Transformer

10.7. Transformer — 动手学深度学习 2.0.0 documentation (d2l.ai) 代码 import math import pandas as pd import torch from torch import nn from d2l import torch as d2l#save class PositionWiseFFN(nn.Module):"""基于位置的前馈网络""&qu…

【uni-best+UView】使用mitt实现自定义错误对话框

痛点 目前在设计一个uni-best的前端全局的异常提示信息&#xff0c;如果采用Toast方式&#xff0c;对微信支持的不友好。微信的7中文长度连个NPE信息都无法完整显示&#xff0c;更不用提Stacktrace的复杂报错了。如果使用对话框&#xff0c;必须在页面先预先定义&#xff0c;对…

C/C++ 进阶(2)多态

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;C 目录 一、多态的概念 二、多态的定义及其实现 1、多态的构成条件 2、虚函数 3、虚函数重写 a.常规 b.两个例外 1、协变&#xff08;基类与派生类虚函数返回值类型不同&#xff09; 2、析构函数重…

10G UDP协议栈 (9)UDP模块

目录 一、UDP协议简单介绍 二、UDP功能实现 三、仿真 一、UDP协议简单介绍 UDP协议和TCP协议同位于传输层&#xff0c;介于网络层&#xff08;IP&#xff09;和应用层之间&#xff1a;UDP数据部分为应用层报文&#xff0c;而UDP报文在IP中承载。 UDP 报文格式相对于简单&am…

单工无线发射接收系统

1 绪论 随着无线电技术的发展,通讯方式也从传统的有线通讯逐渐转向无线通讯。由于传统的有线传输系统有配线的问题,较不便利,而无线通讯具有成本廉价、建设工程周期短、适应性好、扩展性好、设备维护容易实现等特点,故未来通讯方式将向无线传输系统方向发展。同时,实现系…

leedcode【203】. 移除链表元素——Java解法

Problem: 203. 移除链表元素 题目思路解题方法复杂度Code效果 题目 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val…

【图解IO与Netty系列】IO多路复用

IO多路复用 为什么要使用IO多路复用Linux的IO多路复用接口selectpollepoll 为什么要使用IO多路复用 我们常用的IO模型是BIO&#xff0c;我们Java里的IO流大多数都是BIO&#xff0c;也就是同步阻塞式IO&#xff0c;这种IO操作的好处是简单方便&#xff0c;但是缺点也很明显——…

【技术实操】银河高级服务器操作系统实例分享,TCP长连接与短连接详细说明

1.服务器环境以及配置 物理机/虚拟机/云/容器 物理机 处理器&#xff1a; HUAWEI Kunpeng 920 具体操作系统版本 Kylin-Server-10-SP1-Release-Build20-20210518- aarch64 内核版本 kernel-4.19.90-23.8.v2101.ky10.aarch64 2.问题现象描述 对TCP长连接有疑问 1、如何…

Yolov8训练自己的数据集(脱离ultralytics库)

最近在整理关于yolov8的相关内容&#xff0c;有个很大的问题&#xff0c;抛开yolov8性能不谈&#xff0c;yolov8代码的使用灵活性不如yolov5&#xff0c;尤其是对于一些新手或者对yolo框架不是很熟悉的人(这也是因人而异&#xff0c;有些人可能会喜欢v8代码的使用方式)。比如在…

牛客网刷题 | BC94 反向输出一个四位数

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 将一个四位数&…