当前位置: 首页 > news >正文

(C语言)队列实现与用队列实现栈

目录

1.队列

1.1队列的概念及结构

1.2 队列的实际应用联想

1.3队列的实现

2. 队列应用——队列实现栈

主要思路


1.队列

1.1队列的概念及结构

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

1.2 队列的实际应用联想

1. 基于队列的特点--先进先出,可以联想到大厅服务中的叫号机先到的先拿号,先拿号的先办业务,队列中的人是在等的人,办完业务为出队列,取号为如队列。

2. 也可以是查找和自己间接相关的人,像是查找qq好友的好友,开始自己在队列中,后来将自己出队列,将自己好友入队列,再将队列中的人出来,他们的好友再入队列,当然入队列的时候肯定有限制,不能是和之前重复的,以此类推,即可知道和自己外围相关的人,

注(仅为有代码新人的有端联想,不一定真正适合这些情况)

1.3队列的实现

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
下面我们来实现队列:
分两个文件:Queue.h与Queue.c
Queue.h进行头文件和函数的声明,以及队列结构的创建
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>//方便后面对不同数据的操作
typedef int QDataType;//链式队列-队列结点结构体
typedef struct QListNode
{QDataType _data;struct	QListNode* _pnext;
}QNode;//队列结构体
typedef struct Queue
{QNode* _phead;QNode* _ptail;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);

Queue.c进行队列相关函数的实现

#include "Queue.h"//队列初始化
void QueueInit(Queue* pst)
{assert(pst);pst->_phead = pst->_ptail = NULL;pst->_size = 0;
}// 队尾入队列
void QueuePush(Queue* pst,QDataType x)
{assert(pst);QNode* newnode = (QNode*)malloc(sizeof(QNode));newnode->_data = x;newnode->_pnext = NULL;if (pst->_phead == NULL){pst->_phead = pst->_ptail = newnode;}else{pst->_ptail->_pnext = newnode;pst->_ptail = newnode;}pst->_size++;
}// 队头出队列
void QueuePop(Queue* pst)
{assert(pst);assert(pst->_size);QNode* next = pst->_phead->_pnext;free(pst->_phead);pst->_phead = next;pst->_size--;
}// 获取队列队尾元素
QDataType QueueBack(Queue* pst)
{assert(pst);assert(pst->_size);return pst->_ptail->_data;
}// 获取队列头部元素
QDataType QueueFront(Queue* pst)
{assert(pst);assert(pst->_size);return pst->_phead->_data;
}// 获取队列中有效元素个数
int QueueSize(Queue* pst)
{assert(pst);return pst->_size;
}// 检测队列是否为空,如果为空返回True,如果非空返回False 
bool QueueEmpty(Queue* pst)
{assert(pst);return pst->_size == 0;
}// 销毁队列
void QueueDestroy(Queue* pst)
{assert(pst);QNode* cur = pst->_phead;while (cur){QNode* next = cur->_pnext;free(cur);cur = next;}pst->_size = 0;pst->_phead = pst->_ptail = NULL;
}

2. 队列应用——队列实现栈

225. 用队列实现栈 - 力扣(LeetCode)

题目:

我们用直接使用前队列的代码实现栈。

主要思路

创建两个队列相互导数据实现后进先出的效果,;压数据时直接在有数据的那个队列中插入数据,出栈时将有数据的队列中的size-1个数据导入另一个队列里,则第一个队列中剩下的那个数据是我们要出栈的数据,这就是主要思路。

下面是代码演示:(代码有点长但是前面的大部分都是前面实现队列的代码,直接复制粘贴的)

typedef int QDataType;
// 链式队列-队列结点结构体
typedef struct QListNode {QDataType _data;struct QListNode* _pnext;
} QNode;// 队列结构体
typedef struct Queue {QNode* _phead;QNode* _ptail;int _size;
} Queue;// 队列初始化
void QueueInit(Queue* pst) {assert(pst);pst->_phead = pst->_ptail = NULL;pst->_size = 0;
}// 队尾入队列
void QueuePush(Queue* pst, QDataType x) {assert(pst);QNode* newnode = (QNode*)malloc(sizeof(QNode));newnode->_data = x;newnode->_pnext = NULL;if (pst->_phead == NULL) {pst->_phead = pst->_ptail = newnode;} else {pst->_ptail->_pnext = newnode;pst->_ptail = newnode;}pst->_size++;
}// 队头出队列
void QueuePop(Queue* pst) {assert(pst);assert(pst->_size);QNode* next = pst->_phead->_pnext;free(pst->_phead);pst->_phead = next;pst->_size--;
}// 获取队列队尾元素
QDataType QueueBack(Queue* pst) {assert(pst);assert(pst->_size);return pst->_ptail->_data;
}// 获取队列头部元素
QDataType QueueFront(Queue* pst) {assert(pst);assert(pst->_size);return pst->_phead->_data;
}// 获取队列中有效元素个数
int QueueSize(Queue* pst) {assert(pst);return pst->_size;
}// 检测队列是否为空,如果为空返回True,如果非空返回False
bool QueueEmpty(Queue* pst) {assert(pst);return pst->_size == 0;
}// 销毁队列
void QueueDestroy(Queue* pst) {assert(pst);QNode* cur = pst->_phead;while (cur) {QNode* next = cur->_pnext;free(cur);cur = next;}pst->_size = 0;pst->_phead = pst->_ptail = NULL;
}typedef struct {Queue p1;Queue p2;
} MyStack;MyStack* myStackCreate() {MyStack* st = (MyStack*)malloc(sizeof(MyStack));QueueInit(&(st->p1));QueueInit(&(st->p2));return st;
}void myStackPush(MyStack* obj, int x) {if (!QueueEmpty(&(obj->p1))) {QueuePush(&(obj->p1), x);} else {QueuePush(&(obj->p2), x);}
}int myStackPop(MyStack* obj) {Queue* empty = &(obj->p1);Queue* nonempty = &(obj->p2);if (!QueueEmpty(empty)) {empty = &(obj->p2);nonempty = &(obj->p1);}while (QueueSize(nonempty) > 1) {QueuePush(empty, QueueFront(nonempty));QueuePop(nonempty);}int ret = QueueFront(nonempty);QueuePop(nonempty);return ret;
}int myStackTop(MyStack* obj) {if (!QueueEmpty(&obj->p1)) {return QueueBack(&(obj->p1));} else {return QueueBack(&(obj->p2));}
}
bool myStackEmpty(MyStack* obj) {return QueueEmpty(&(obj->p1)) && QueueEmpty(&(obj->p2));
}void myStackFree(MyStack* obj) {QueueDestroy(&(obj->p1));QueueDestroy(&(obj->p2));free(obj);
}

各位看官姥爷点个赞再走吧,欢迎在评论区讨论。

http://www.lryc.cn/news/349990.html

相关文章:

  • 字符画生成网站 ascii字符画
  • 【C -> Cpp】由C迈向Cpp (6):静态、友元和内部类
  • 探索Playwright:Python下的Web自动化测试革命
  • 先有JVM还是先有垃圾回收器?很多人弄混淆了
  • 关于 vs2019 c++20 规范里的一个全局函数 _Test_callable
  • 07-Fortran基础--Fortran指针(Pointer)的使用
  • 日期差值,
  • GMV ES6直流变频多联空调机组室外机工作原理
  • 中国开源 AI 大模型之光-InternLM2
  • 【嵌入式开发】Arduino人机界面及接口技术:独立按键接口,矩阵按键接口,模拟量按键接口(基础知识介绍)
  • element ui Tree树形控件
  • AI 绘画神器 Fooocus 图生图:图像放大或变化、图像提示、图像重绘或扩充、反推提示词、生成参数提取、所需模型下载
  • yolov8 模型架构轻量化 | 极致降参数量
  • uniapp 小程序低功耗蓝牙配网 ble配网 物联网
  • 服务器防火墙有什么用防护策略
  • 27.哀家要长脑子了!
  • Redis实战—验证码登录注册
  • 对话机器人技术解说
  • 红黑树底层封装map、set C++
  • 压力给到 Google,OpenAI 发布 GPT-4o 来了
  • 【SpringSecurity源码】过滤器链加载流程
  • 第9章.Keil5-MDK软件简介
  • mysql中utf8字符集中文字节长度统计如何统计到2个字节一个汉字
  • 如何实现Linux双网卡同时连接内网和外网的配置?
  • ASCLL码表以及字符的相加减
  • 一键修复所有dll缺失,教大家解决丢失的dll文件
  • wsl2安装rancher并导入和创建k8s集群
  • 内网环境ubuntu设置静态ip、DNS、路由,不影响网络访问
  • 学习前端第三十七天(静态属性静态方法、类检查、错误处理)
  • 全网最全的基于电机控制的38类simulink仿真全家桶----新手大礼包