队列Queue

结构特点:先进先出

实现模式:单向非循环双指针链表

两个指针分别记录头和尾之所以不用循环链表是添加删除元素都在链表头部进行,不涉及尾部增删操作。

声明队列 

声明队列之所以要用到两个结构体是因为除了单个链表节点之外,还需要一个尾指针记录队尾。 

typedef int QDataType;
typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QNode;
struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
};

初始化

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)
	{
		QNode* Next =cur->next;
		free(cur);
		cur = Next;
	}
	pq->head = pq->tail = NULL;//避免野指针
    pq->size = 0;
}

Push

由于只在头部插入数据,所以不需要再对是否新增一个节点额外封装一层函数。

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;
	pq->size++;

	if (pq->head == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

判空

bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL && pq->tail == NULL;//其中一个为空即可
}

Pop

出队是在头删除节点,注意只有一个节点需要将头尾指针置空没有节点需要进行断言等检查。

void QueuePop(Queue* pq)
{
	//出队头删
	assert(pq);
	assert(!QueueEmpty(pq));
	Queue* del = pq->head;
	pq->head = pq->head->next;//一个节点next为NULL
	free(del);
	if (pq->head == NULL)
		pq->tail = NULL;
	pq->size--;

}

Size

size的作用是记录节点的个数,我们可以通过遍历得到个数,但时间复杂度为O(n),这时我们定义的结构体成员size就发挥作用了,直接返回即可。

int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

Front

同理,直接调用可能不知道存在哨兵节点等问题。

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->data;
}

Back

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->tail->data;
}

测试

完整代码

//Queue.h
#pragma once
#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef int QDataType;
typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QNode;
struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
};
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);

 

//Queue.cpp
#include "Queue.h"
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* Next =cur->next;
		free(cur);
		cur = Next;
	}
	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;
	pq->size++;

	if (pq->head == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}
void QueuePop(Queue* pq)
{
	//出队头删
	assert(pq);
	assert(pq->head);
	QNode* del = pq->head;
	pq->head = pq->head->next;
	free(del);
	if (pq->head == NULL)
		pq->tail = NULL;
	pq->size--;
	 
}
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = NULL;
	pq->tail = NULL;
	pq->size = 0;
}
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL && pq->tail == NULL;
}
int QueueSize(Queue* pq)
{
	assert(pq);
	return 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;
}
//test.cpp
#include "Queue.h"
void Test1()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);

	/*printf("%d ", QueueFront(&q));*/
	//QueuePop(&q);

	QueuePush(&q, 3);
	QueuePush(&q, 4);

	//printf("%d\n", QueueSize(&q));
	//printf("%d\n", QueueEmpty(&q));
	//printf("%d\n", QueueFront(&q));
	//printf("%d\n", QueueBack(&q));
	//打印--先进先出
	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	printf("\nsize:%d\n", QueueSize(&q)); 
	printf("%d\n", QueueEmpty(&q));
	QueueDestroy(&q);
}
int main()
{
	Test1();

	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

js删除json数据中指定元素

delete 删除数组方法&#xff1a; function removeJSONRows() {var tab {"dataRows": [{"id": 1,"name": "使用部门"},{"id": 2,"name": "车辆走行路线"},{"id": 3,"name": &quo…

合并二叉树(Java)

题目描述 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xff0c;两棵树上的一些节点将会重叠&#xff08;而另一些不会&#xff09;。你需要将这两棵树合并成一棵新二叉树。合并的规则是&#xff1a;如果两个节点重…

Java的类与Golang的结构体的区别

Java作为一门面向对象&#xff08;OOP&#xff09;的编程语言&#xff0c;它有类&#xff08;class&#xff09;的存在&#xff0c;而对于Golang&#xff0c;它不完全遵从OOP编程语言的设计思想&#xff0c;但它也有类似Java类的结构存在&#xff0c;那就是结构体&#xff08;s…

左值右值笔记

左值右值 左值 左值是表示数据的表达式&#xff08;如变量名或解引用的指针&#xff09; 特点&#xff1a;可以获取地址&#xff0c;可以对他赋值。 位置&#xff1a;左值可以出现在赋值符号左边&#xff0c;也可以出现在赋值符号右边 右值 右值有:字面常量, 表达式返回值 …

2020年-2022年聚合支付牌照机构评级结果分析,D/E有所增加

本文首发于移动支付网&#xff0c;标题“聚合支付机构最新评级结果公布&#xff0c;A-、B级别机构减少”&#xff0c;该文是基于其内容进行了数据修订及部分内容优化而成文。 11月7日&#xff0c;中国支付清算协会发布2022年度收单外包服务机构评级等级结果。本次评级工作&…

在 Azure 上构建和部署自然语言处理模型

自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;是人工智能领域中的重要分支之一&#xff0c;它涉及对人类语言进行理解和分析。在 Azure 平台上&#xff0c;我们可以利用丰富的工具和服务来构建和部署自然语言处理模型&#xff0c;实现从文本…

免费3D骨架工具

免费3D骨架工具 : https://posemy.art/ ControlNet 1.1http://www.coloradmin.cn/o/839105.html?actiononClick https://pan.baidu.com/s/1rh39DI9xVbguLO5l7O4pjA yqqe  网盘里的 预处理器/downloads文件夹&#xff08;包含所有预处理器&#xff09;直接放在 extensions/sd…

【LeetCode刷题-二分查找】--278.第一个错误的版本

278.第一个错误的版本 /* The isBadVersion API is defined in the parent class VersionControl.boolean isBadVersion(int version); */public class Solution extends VersionControl {public int firstBadVersion(int n) {int left 1,right n;while(left < right){int…

企业知识库建设指南:实用经验分享

企业知识库建设是提升内部协作和客户支持效率的重要举措。一个完善的知识库可以帮助企业集中管理和传播知识&#xff0c;提供便捷的自助服务和丰富的编辑工具&#xff0c;从而提升用户体验和品牌好感度。接下来就分享一些经验&#xff0c;关于该如何构建一个高效的企业知识库。…

TCP协议(建议收藏)

1. TCP特点 有连接&#xff1a;需要双方建立连接才能通信&#xff0c;在socket编程中服务端new ServerSocket(port)需要绑定端口&#xff0c;在客服端new Socket(serverIp, serverPort)与服务端建立连接可靠传输&#xff1a;确认应答机制&#xff0c;超时重传机制面向字节流&a…

【文末送JAVA书】包头开发发展

【点我-这里送书】 本人详解 作者&#xff1a;王文峰&#xff0c;参加过 CSDN 2020年度博客之星&#xff0c;《Java王大师王天师》 公众号&#xff1a;JAVA开发王大师&#xff0c;专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生&#xff0c;期待你的…

jbase支持连IRIS

jbase设计的时候就抽取了IDbFactory接口&#xff0c;支持不同数据库只要配置该接口实现类即可&#xff0c;那么就用IRIS测试下多数据库支持。 首先从IRIS安装目录拷贝jar包 然后实现数据库驱动接口 package LIS.Dal.Base;import LIS.Core.MultiPlatform.LISConfigurtaion;…

Java基础(第六期):Java基础巩固、逢七跳过、数组求和、判断数组是否相等、数组逆置、元素位置查找、评委打分、随机产生验证码

Java基础专栏【点击跳转学习】 Java基础&#xff08;第六期&#xff09;&#xff1a;对前五期的综合练习 文章目录 综合练习巩固JAVA基础第六期一、逢 7 跳过二、数组元素求和三、判断两个数组元素是否相同四、查找元素在数组中的索引五、数组元素反转使用for循环的实现方式一、…

MySQL中的索引

目录 一、概念 二、作用和特点 作用 特点 三、使用场景 四、使用 1、查看索引 2、创建索引 3、删除索引 五、索引底层数据结构的实现 B树&#xff08;B-树&#xff09; B树 特点 重复出现的好处 一、概念 索引 翻译成英文&#xff1a;index&#xff08;下标&#xf…

Doris学习--1、Doris简介、操作Doris、Doris架构(数据模型)

星光下的赶路人star的个人主页 心之所向&#xff0c;剑之所往 文章目录 1、Doris简介1.1 快速开始1.2 安装配置1.2.1 应知前提1.2.2 配置Doris1.2.2.0 配置前提1.2.2.1 配置FE&#xff08;Frontend&#xff09;1.2.2.2 启动FE1.2.2.3 连接FE1.2.2.4 停止FE1.2.2.5 配置BE&#…

InSAR形变监测方法与研究进展(朱建军,中南大学)

文章目录 摘要引言InSARInSAR原理SAR卫星 InSAR监测技术D-InSARMT-InSARPS-InSARSBAS-InSARDS-InSAR&#xff08;Distributed Scatterer InSAR&#xff09;MAI&#xff08;Multi-Aperture InSAR, 多孔径InSAR&#xff09; InSAR形变监测应用与发展城市沉降监测矿山形变监测地震…

深度探究深度学习常见数据类型INT8 FP32 FP16的区别即优缺点

定点和浮点都是数值的表示&#xff08;representation&#xff09;&#xff0c;它们区别在于&#xff0c;将整数&#xff08;integer&#xff09;部分和小数&#xff08;fractional&#xff09;部分分开的点&#xff0c;点在哪里。定点保留特定位数整数和小数&#xff0c;而浮点…

SpringBoot学习(黑马程序员day12)

1jwt令牌 JWT的组成&#xff1a; &#xff08;JWT令牌由三个部分组成&#xff0c;三个部分之间使用英文的点来分割&#xff09; 第一部分&#xff1a;Header(头&#xff09;&#xff0c; 记录令牌类型、签名算法等。 例如&#xff1a; {"alg":"HS256",&qu…

【已解决】ModuleNotFoundError: No module named ‘matplotlib‘

问题描述 Traceback (most recent call last): File "/home/visionx/nickle/temp/SimCLR/linear_evaluation.py", line 207, in <module> import matplotlib.pyplot as plt ModuleNotFoundError: No module named matplotlib 解决办法 pip install matp…