07 队列

news2024/12/27 10:04:37

目录

1.队列
2.实现
3.OJ题


1. 队列

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

在这里插入图片描述

2. 实现

队列可以用数组和链表的结构实现,需要从两端出操作数据,所以用链表的结构更优一点

在这里插入图片描述

队列的设计需要两层结构体,一层结构体是节点结构体,另一层是队列结构

头文件

#pragma once
#include <stdbool.h>

typedef int DATATYPE;

//节点
typedef struct _Node
{
	DATATYPE data;
	struct _Node* next;
}Node;

//队列
typedef struct _Queue
{
	struct _Node* head;
	struct _Node* tail;
	int size;
}Queue;

// 初始化
void Init(Queue* que);
// 入队
void Push(Queue* que, DATATYPE data);
// 出队
void Pop(Queue* que);
// 是否为空
bool Empty(Queue* que);
// 返回队首
DATATYPE Front(Queue* que);
// 返回队尾
DATATYPE Back(Queue* que);
// 队列大小
int Size(Queue* que);
// 销毁
void Destory(Queue* que);

实现文件

#include "Queue.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

void Init(Queue* que)
{
	assert(que);
	//置空
	que->head = que->tail = NULL;
	que->size = 0;
}

void Push(Queue* que, DATATYPE data)
{
	assert(que);

	Node* newnode = (Node*)malloc(sizeof(Node));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}

	newnode->data = data;
	newnode->next = NULL;
	//空队,不为空
	if (que->head == NULL)
	{
		//防止一个空,另一个不为空
		assert(que->tail == NULL);
		que->head = que->tail = newnode;
	}
	else
	{
		que->tail->next = newnode;
		que->tail = newnode;
	}

	que->size++;
}

void Pop(Queue* que)
{
	assert(que);
	assert(!Empty(que));

	//一个节点,多个节点
	if (que->head->next == NULL)
	{
		free(que->head);
		que->head = que->tail = NULL;
	}
	else
	{
		//头删
		Node* del = que->head;
		que->head = que->head->next;
		free(del);
	}
	que->size--;
}

bool Empty(Queue* que)
{
	assert(que);
	//que.head == NULL && que.tail == NULL
	return que->size == 0;
}

DATATYPE Front(Queue* que)
{
	assert(que);
	assert(!Empty(que));

	return que->head->data;
}

DATATYPE Back(Queue* que)
{
	assert(que);
	assert(!Empty(que));

	return que->tail->data;
}

int Size(Queue* que)
{
	assert(que);

	return que->size;
}

void Destory(Queue* que)
{
	assert(que);

	Node* cur = que->head;
	while (cur != NULL)
	{
		Node* del = cur;
		cur = cur->next;
		free(del);
	}

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


主文件

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "Queue.h"

int main()
{
	Queue que;
	Init(&que);
	Push(&que, 1);
	Push(&que, 2);
	Push(&que, 3);
	Push(&que, 4);
	printf("%d ", Front(&que));
	printf("%d \r\n", Back(&que));
	Pop(&que);
	while (!Empty(&que))
	{
		printf("%d ", Front(&que));
		printf("%d \r\n", Back(&que));
		Pop(&que);
	}
	Destory(&que);
	return 0;
}


3. OJ题

3.1 用队列实现栈

https://leetcode.cn/problems/implement-stack-using-queues/description/
在这里插入图片描述

思路
利用前面写的队列。用队列实现栈的关键点在于,队列是先进先出,栈是先进后出。这时,可以用两个栈,需要出数据时将一个栈的所有数据捯到另一个栈中,留下最后一个数据,然后出队,这个就是栈的栈顶元素。每次需要出数据反复这样。入数据时,找一个不为空的入,不为空的出数据捯一遍后,刚好剩下刚进入的数据,栈为空也可以这样

在这里插入图片描述

//引入队列
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int DATATYPE;

//节点
typedef struct _Node
{
	DATATYPE data;
	struct _Node* next;
}Node;

//队列
typedef struct _Queue
{
	struct _Node* head;
	struct _Node* tail;
	int size;
}Queue;

void Init(Queue* que)
{
	assert(que);
	//置空
	que->head = que->tail = NULL;
	que->size = 0;
}

void Push(Queue* que, DATATYPE data)
{
	assert(que);

	Node* newnode = (Node*)malloc(sizeof(Node));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}

	newnode->data = data;
	newnode->next = NULL;
	//空队,不为空
	if (que->head == NULL)
	{
		//防止一个空,另一个不为空
		assert(que->tail == NULL);
		que->head = que->tail = newnode;
	}
	else
	{
		que->tail->next = newnode;
		que->tail = newnode;
	}

	que->size++;
}

bool Empty(Queue* que)
{
	assert(que);
	//que.head == NULL && que.tail == NULL
	return que->size == 0;
}
void Pop(Queue* que)
{
	assert(que);
	assert(!Empty(que));

	//一个节点,多个节点
	if (que->head->next == NULL)
	{
		free(que->head);
		que->head = que->tail = NULL;
	}
	else
	{
		//头删
		Node* del = que->head;
		que->head = que->head->next;
		free(del);
	}
	que->size--;
}

DATATYPE Front(Queue* que)
{
	assert(que);
	assert(!Empty(que));

	return que->head->data;
}

DATATYPE Back(Queue* que)
{
	assert(que);
	assert(!Empty(que));

	return que->tail->data;
}

int Size(Queue* que)
{
	assert(que);

	return que->size;
}

void Destory(Queue* que)
{
	assert(que);

	Node* cur = que->head;
	while (cur != NULL)
	{
		Node* del = cur;
		cur = cur->next;
		free(del);
	}

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


//------------------------------------------------------------------------
//实现栈
typedef struct {
    Queue que1;
    Queue que2;
} MyStack;


MyStack* myStackCreate() {
    
    MyStack* stk = (MyStack*)malloc(sizeof(MyStack));
    Init(&stk->que1);
    Init(&stk->que2);
    return stk;
}

void myStackPush(MyStack* obj, int x) {
    //往空队列插入
    if(Empty(&obj->que1))
        Push(&obj->que1, x);
    else
        Push(&obj->que2, x);
}

int myStackPop(MyStack* obj) {
    
    //定义空和非空,如果错误交换
    Queue* empty = &obj->que1;
    Queue* noempty = &obj->que2;

    if(Empty(&obj->que2))
    {
        empty = &obj->que2;
        noempty = &obj->que1;
    }
    //非空的大于1个往另一个队列捯
    while(Size(noempty) > 1)
    {
        Push(empty, Front(noempty));
        Pop(noempty);
    }

    int x = Front(noempty);
    Pop(noempty);
    return x;
}


int myStackTop(MyStack* obj) {

  //定义空和非空,如果错误交换
    Queue* empty = &obj->que1;
    Queue* noempty = &obj->que2;

    if(Empty(&obj->que2))
    {
        empty = &obj->que2;
        noempty = &obj->que1;
    }

    return Back(noempty);
}

bool myStackEmpty(MyStack* obj) {
    
    return Empty(&obj->que1) && Empty(&obj->que2);
}

void myStackFree(MyStack* obj) {
    Destory(&obj->que1);
    Destory(&obj->que2);
    free(obj);
}

/**
 * Your MyStack struct will be instantiated and called as such:
 * MyStack* obj = myStackCreate();
 * myStackPush(obj, x);
 
 * int param_2 = myStackPop(obj);
 
 * int param_3 = myStackTop(obj);
 
 * bool param_4 = myStackEmpty(obj);
 
 * myStackFree(obj);
*/

3.2 栈实现队列

https://leetcode.cn/problems/implement-queue-using-stacks/

在这里插入图片描述

思路
利用实现的栈。栈实现队列同样需要两个栈,由于栈是先进后出,当我们捯一遍数据后,刚好会把所有数据顺序反过来,所以只需要捯一次。利用这种特性,可以将两个栈分为只仅数据的和出数据的。刚开始出栈为空,需要出数据时,从入栈捯数据过来然后出栈顶元素

在这里插入图片描述

//引用栈结构
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int DATATYPE;

typedef struct _Stack
{
	DATATYPE* ary;
	int top;        //指向下一个存放数据的位置
	int capacity;
}Stk;


void Init(Stk* stack)
{
    assert(stack);

    stack->ary = NULL;
    stack->top = 0;   //指向栈顶下一个位置
    stack->capacity = 0;
}

void Push(Stk* stack, DATATYPE data)
{
    assert(stack);

    //需要扩容
    if (stack->top == stack->capacity)
    {
        int newcap = stack->capacity == 0 ? 4 : stack->capacity * 2;
        DATATYPE* temp = (DATATYPE*)realloc(stack->ary, sizeof(DATATYPE) * newcap);
        if (temp == NULL)
        {
            perror("realloc fail");
            return;
        }
        
        stack->ary = temp;
        stack->capacity = newcap;  
    }
    //存数据
    stack->ary[stack->top] = data;
    stack->top++;
}

bool Empty(Stk* stack)
{
    assert(stack);

    return stack->top == 0;
}

void Pop(Stk* stack)
{
    assert(stack);
    assert(!Empty(stack));

    stack->top--;
}

DATATYPE Top(Stk* stack)
{
    assert(stack);
    assert(!Empty(stack));

    return stack->ary[stack->top - 1];
}

int Size(Stk* stack)
{
    assert(stack);

    return stack->top;
}

void Destory(Stk* stack)
{
    assert(stack);

    free(stack->ary);
    stack->ary = NULL;
    stack->capacity = 0;
    stack->top = 0;
}

//------------------------------------------------------------------------
//实现队列
typedef struct {
    Stk stpush;
    Stk stpop;
} MyQueue;


MyQueue* myQueueCreate() {
    
    MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
    Init(&obj->stpush);
    Init(&obj->stpop);

    return obj;
}

void myQueuePush(MyQueue* obj, int x) {
    
    Push(&obj->stpush, x);
}

int myQueuePop(MyQueue* obj) {
   
    int ch = myQueuePeek(obj);
    Pop(&obj->stpop);
    return ch;
}

int myQueuePeek(MyQueue* obj) {
    if(Empty(&obj->stpop))
    {
        while(!Empty(&obj->stpush))
        {
            Push(&obj->stpop, Top(&obj->stpush));
            Pop(&obj->stpush);
        }
    }
    return Top(&obj->stpop);
}

bool myQueueEmpty(MyQueue* obj) {
    
    return Empty(&obj->stpush) && Empty(&obj->stpop);
}

void myQueueFree(MyQueue* obj) {
    Destory(&obj->stpush);
    Destory(&obj->stpop);
    free(obj);
}

/**
 * Your MyQueue struct will be instantiated and called as such:
 * MyQueue* obj = myQueueCreate();
 * myQueuePush(obj, x);
 
 * int param_2 = myQueuePop(obj);
 
 * int param_3 = myQueuePeek(obj);
 
 * bool param_4 = myQueueEmpty(obj);
 
 * myQueueFree(obj);
*/

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

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

相关文章

PWM调光 降压恒流LED芯片FP7127:为照明系统注入新能量(台灯、GBR、调光电源、汽车大灯)

目录 一、降压恒流LED芯片FP7127 二、降压恒流LED芯片FP7127具有以下特点&#xff1a; 三、降压恒流LED芯片FP7127应用领域&#xff1a; LED照明和调光的新纪元随着LED照明技术的不断发展&#xff0c;人们对于照明调光的需求也越来越高。PWM调光技术作为一种常用的调光方法&…

微软 AD 介绍 | 安全建议 | 防护

介绍&#xff1a; 什么是Active Directory&#xff08;AD&#xff09;&#xff1f; Active Directory 是由 微软开发的目录服务&#xff0c;用于存储和管理网络中的资源&#xff0c;如计算机、用户、组和其他网络对象。允许组织管理员轻松地管理和验证网络中的用户和计算机。 …

解决Sublime Text V3.2.2中文乱码问题

目录 中文乱码出现情形通过安装插件来解决乱码问题 中文乱码出现情形 打开一个中文txt文件&#xff0c;显示乱码&#xff0c;在File->Reopen With Encoding里面找不到支持简体中文正常显示的编码选项。 通过安装插件来解决乱码问题 安装Package Control插件 打开Tool->…

[IO复用] IO复用问答

记录一下IO复用相关的基础知识。 文章目录 阻塞和非阻塞同步和异步为什么使用IO复用什么是IO复用IO复用有哪些方式select IO复用poll IO复用epoll IO复用什么时候用select 或者 epoll&#xff1f; select、poll、epoll的区别Windows中的IO复用Reactor模式C10K问题C10M问题 面试…

【时间序列篇】基于LSTM的序列分类-Pytorch实现 part3 化为己用

系列文章目录 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part1 案例复现 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part2 自有数据集构建 【时间序列篇】基于LSTM的序列分类-Pytorch实现 part3 化为己用 在一个人体姿态估计的任务中&#xff0c;需要用深度学习模型…

【Vue3】组件通信

Vue3组件通信和Vue2的区别&#xff1a; 移出事件总线&#xff0c;使用mitt代替。vuex换成了pinia。把.sync优化到了v-model里面了。把$listeners所有的东西&#xff0c;合并到$attrs中了。$children被砍掉了。 1. props 若 父传子&#xff1a;属性值是非函数。若 子传父&…

【解决】IntelliJ IDEA 重命名 Shift + F6 失效

IntelliJ IDEA 重命名 Shift F6 失效 问题解决 问题 Idea 重命名 Shift F6 &#xff0c;一直没反应 解决 调查发现原因是微软新版的输入法冲突了。需要设置【使用以前版本的微软拼音输入法】解决兼容性。 设置 -> 时间和语言 -> 区域 -> 语言选项 -> 键盘选项…

ELK之使用Grafana读取ES集群的Nginx日志进行分析展示

一、前提&#xff1a; 直通车 ------------>↓↓↓↓↓↓ 需要ES集群 https://blog.csdn.net/wdy_2099/article/details/125441436需要filebeat https://blog.csdn.net/wdy_2099/article/details/125445893需要logstash https://blog.csdn.net/wdy_2099/article/details/1…

技术变革下职业危机

方向一&#xff1a;技术变革 1.人工智能&#xff08;AI&#xff09;&#xff1a;AI技术的快速发展正在改变各个行业。AI在医疗诊断、金融分析、客户服务以及物流管理等方面都有广泛应用&#xff0c;提高了效率和准确性。但同时也引发了一些道德和道德问题&#xff0c;比如隐私…

Redis的五种常用数据类型详解及相关面试问题

目录 Redis的五种常用数据类型详解 简述 Redis五种基本数据类型 String字符串 常用命令 应用场景 Hash散列表 常用命令 使用场景 List链表 常用命令 应用场景 Set( 集合) 常用命令 应用场景 SortedSet( 有序集合) zset 常用命令介绍 应用场景 面试题常问的数…

【MySQL】打开科技创新的第一生产力

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-EtRkflNU19AGWAkT {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

景联文科技大模型数据集更新!教育题库新增高质量数学题、逻辑推理题及英文题

苏格拉底曾以“点燃火焰”的理念来诠释教育。随着大语言模型在教育中的不断应用&#xff0c;教育与AI的深度融合&#xff0c;让我们看到了“点燃火焰”的理念的更多可能性。 大语言模型可以通过与学生的互动&#xff0c;为他们提供个性化的学习体验&#xff0c;更好地满足学习需…

Maven简述

Maven是用于管理和构建Java项目的工具&#xff0c;提供了一套标准化的项目结构&#xff0c;提供了一套标准化的构建流程&#xff0c;提供了一套依赖管理机制&#xff0c;通过Maven使得所有IDE构建的项目结构完全一样&#xff0c;让项目可以通用。 项目名称下分为src 和 pom.xm…

差分进化算法求解基于移动边缘计算 (MEC) 的无线区块链网络的联合挖矿决策和资源分配(提供MATLAB代码)

一、优化模型介绍 在所研究的区块链网络中&#xff0c;优化的变量为&#xff1a;挖矿决策&#xff08;即 m&#xff09;和资源分配&#xff08;即 p 和 f&#xff09;&#xff0c;目标函数是使所有矿工的总利润最大化。问题可以表述为&#xff1a; max ⁡ m , p , f F miner …

Linux系统SSH远程管理服务

目录 一、SSH服务介绍 1、SSH协议是什么&#xff1f; 2、SSH的优点 3、SSH的客户端与服务端 4、SSH的原理 4.1 公钥首次连接原理 4.2 ssh加密通讯原理 4.2.1 对称加密 4.2.2 非对称加密 4.2 ssh远程登录 二、服务端配置 1、常见配置项 1.1 修改默认端口 1.2 禁止…

Transformer and Pretrain Language Models3-1

content transformer attention mechanism transformer structure​​​​​​​ pretrained language models language modeling pre-trained langue models(PLMs&#xff09; fine-tuning approaches PLMs after BERT applications of masked LM frontiers of PLMs …

【Godot4自学手册】第四节动画状态机-AnimationTree

各位同学大家好&#xff01;今天继续学习Godot4&#xff0c;本节将要学习AnimationTree&#xff0c;来实现控制主人公的动画。 一、AnimationPlay节点介绍 Godot引擎通过AnimationPlay节点实现了最灵活的动画系统&#xff0c;它几乎可以给godot中的任意节点的任意属性添加动画…

携程基于Jira Cloud的敏捷项目管理实践

好的工具可以满足团队在各个成长阶段的管理诉求 实践一&#xff1a;对齐目标/团队OKR/多团队协作战略项目 实践二&#xff1a;以产品为中心的协作框架 实践三&#xff1a;交付团队管理 实践四&#xff1a;和海外子公司对齐&#xff0c;协作

数灵通丨可以实现抖音引流微信小程序了

抖音作为一款火爆的短视频社交平台&#xff0c;吸引了数亿用户的关注和喜爱。除了观看和制作视频外&#xff0c;抖音还提供了跳转到小程序的功能&#xff0c;让用户可以享受更多功能和乐趣。那么&#xff0c;如何在抖音中跳转到小程序呢&#xff1f;以下是详细解答&#xff1a;…

Android 基础技术——View 的宽高

笔者希望做一个系列&#xff0c;整理 Android 基础技术&#xff0c;本章是关于 View 的宽高 Activity Resume 的时候设置或者获取view的宽高是否有效? 回答&#xff1a;不确定。 首次 onResume 无效&#xff0c;二次 onResume 就有效了。 回顾「Android 基础技术——addView 流…