(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.hqwc.cn/news/704396.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 渗透测试:子域名查询.

什么是 子域名查询. 子域名查询是指通过域名系统(DNS)查找某个域名下的子域名信息。子域名是域名层级结构中的一部分,位于主域名的下一级。子域名查询是网络安全评估和渗透测试中的一个重要步骤,可以帮助安全研究人员更好地了解目标系统的架构和潜在的安全隐患。但在进行子域名…

【C语言习题】12.扫雷游戏

文章目录 1.扫雷游戏分析和设计1.1 扫雷游戏的功能说明1.2游戏界面&#xff1a;1.3游戏的分析和设计1.2.1 数据结构的分析1.2.2 ⽂件结构设计 2.扫雷游戏的代码实现3.代码讲解 1.扫雷游戏分析和设计 1.1 扫雷游戏的功能说明 使用控制台实现经典的扫雷游戏游戏可以通过菜单实现…

07-Fortran基础--Fortran指针(Pointer)的使用

07-Fortran基础--Fortran指针Pointer的使用 0 引言1 指针&#xff08;Poionter&#xff09;的有关内容1.1 一般类型指针1.2 数组指针1.3 派生类(type)指针1.4 函数指针 2 可运行code 0 引言 Fortran是一种广泛使用的编程语言&#xff0c;特别适合科学计算和数值分析。Fortran 9…

第9章.Keil5-MDK软件简介

目录 0. 《STM32单片机自学教程》专栏 9.1 主界面 9.2 文本格式编辑 9.3 代码提示&语法检测&代码模版 9.4 其他小技巧 9.4.1 TAB 键的妙用 9.4.2 快速定位函数/变量被定义的地方 9.4.3 快速注释与快速消注释 9.4.4 快速打开头文件 9.4.5 查找替换…

数据结构初阶 顺序表的补充

一. 题目的要求 写出三种链表的接口函数 它们的功能分别是 1 查找数的位置 2 在pos位置插入值 3 在pos位置删除值 二. 实现pos 这个其实很简单 找到一步步遍历 找到这个数字就返回 找不到就提示用户下 这个数字不存在 int SLFind(SL* ps,SLDateType x) {assert(ps);int…

醉了,面个功能测试,还问我Python装饰器

Python 装饰器是个强大的工具&#xff0c;可帮你生成整洁、可重用和可维护的代码。某种意义上说&#xff0c;会不会用装饰器是区分新手和老鸟的重要标志。如果你不熟悉装饰器&#xff0c;你可以将它们视为将函数作为输入并在不改变其主要用途的情况下扩展其功能的函数。装饰器可…

[ciscn 2022 东北赛区]math

1.题目 import gmpy2 from Crypto.Util.number import * from flag import flag assert flag.startswith(b"flag{") assert flag.endswith(b"}") messagebytes_to_long(flag) def keygen(nbit, dbit):if 2*dbit < nbit:while True:a1 getRandomNBitIn…

(实测验证)【移远EC800M-CN 】TCP 透传

引言 本文章使用自研“超小体积TTL转4GGPS集成模块”进行实测验证&#xff1b; 1、配置移远EC800M-CN TCP 透传 串口助手发送&#xff1a; ATQIOPEN1,0,"TCP","36.137.226.30",39755,0,2 //配置服务器地址和端口号&#xff1b; 4G模组返回…

Go微服务: 接入Prometheus性能监控平台与Grafana平台

接入Prometheus 在 go-micro 生成的模板中, 我们一如既往的完成基础工作之后 进入main.go工作的代码编写&#xff0c;main.go package mainimport ("fmt""log""strconv""github.com/go-micro/plugins/v4/registry/consul"opentracing…

MaxKB创建本地知识库

上节已经可以通过MaxKB创建简单的问答系统了&#xff0c;这节开始做自己的知识库&#xff0c;实际上就是把一些本地文件上传到大模型中&#xff0c;让大模型学会这些文件内容&#xff0c;你在问他问题的时候可以通过此文件的内容来回答你&#xff0c;尤其是在针对特定场景或者特…

(实测验证)Gitee代码托管尝试(一)——克隆/下载

一、登录 Gitee&#xff08;码云&#xff09;代码托管平台&#xff1a; Gitee - 基于 Git 的代码托管和研发协作平台 新建个人账户如下&#xff1a; 二、SSH 公钥设置 1、在git安装目录打开“git-cmd.exe”; 2、通过命令 ssh-keygen 生成 SSH Key&#xff1a; ssh-keygen …

指针在函数的应用(C++)

一、传递地址 实参传递进函数体内后&#xff0c;生成的是实参的副本&#xff0c;在函数内改变副本的值并不影响实参。指针传递参数时&#xff0c;指针变量产生了副本&#xff0c;但副本与原变量指向的内存区域是同一个。改变指针副本指向的变量&#xff0c;就是改变原指针变量指…