首页 > 其他分享 >数据结构(队列)

数据结构(队列)

时间:2024-07-19 23:28:25浏览次数:13  
标签:结点 pq 队列 Queue phead 数据结构 QueueNode

文章目录

一、概念与结构

二、队列的实现

  QueueNode.h

  Queue.c

    初始化

    判断队列为空

    队尾,入队列

    队头,出队列

    取队头数据

    取队尾数据

    取队列有效元素个数

    销毁队列

  test.c


一、概念与结构

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

 

在队列的底层结构的选择上有:

  • 数组:若使用数组为底层结构,进行⼊队列操作的时间复杂度为 O(1) ,进行出队列操作的时间复杂度为 O(n);

  • 单链表:若使用单链表为底层结构,进行⼊队列操作的时间复杂度为 O(n) ,进行出队列操作的时间复杂度为 O(1);

这么看好像两者的差别不大,但是我们在单链表结构中可以稍作改造,直接定义两个结点(头结点,尾结点)指向原链表的队头和队尾,那么在队尾入数据时就不用遍历链表,直接让尾结点->next 等于新结点,时间复杂度就变成 O(1)了。

二、队列的实现

QueueNode.h

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

//定义队列结构
typedef int QDataType;
typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* phead;
	QueueNode* ptail;
	int size;//保存队列有效数据个数
}Queue;

//初始化
void QueueInit(Queue* pq);


// ⼊队列,队尾
void QueuePush(Queue* pq, QDataType x);
// 出队列,队头
void QueuePop(Queue* pq);


//队列判空
bool QueueEmpty(Queue* pq);


//取队头数据
QDataType QueueFront(Queue* pq);

//取队尾数据
QDataType QueueBack(Queue* pq);


//队列有效元素个数
int QueueSize(Queue* pq);

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

Queue.c

初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = pq->ptail = NULL;
	pq->size = 0;

}
 
判断队列为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->phead == NULL && pq->ptail == NULL;
}

 

 
 队尾,入队列
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);

	//申请新结点
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(1);
	
	}
	newnode->data = x;
	newnode->next = NULL;

	//如果原队列为空
	if (pq->phead == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}

	//如果原队列不为空,进行尾插
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = pq->ptail->next;
	}
	pq->size++;    //有效数据个数加一

}

队头,出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	//如果队列为空,不可出队列
	if (pq->phead == NULL)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;   //记得把尾结点也置为空,不然会成为野指针
	}

	else
	{
		QueueNode* n = pq->phead->next;  //创建结点 n 为原头结点指向的下一个结点
		free(pq->phead);                 //释放原队列头结点,也就是出队列
		pq->phead = n;                   //结点 n 为新的队头
	}
}
 
取队头数据
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->phead->data;
}
取队尾数据
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->ptail->data;
}
 
取队列有效元素个数
int QueueSize(Queue* pq) 
{
	assert(pq);
	return pq->size;
}
 
销毁队列
void QueueDestroy(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	QueueNode* pcur = pq->phead;         //创建指针 pcur指向队列头结点遍历队列

	while (pcur)                         //当 pcur 不为空循环
	{
		QueueNode* n = pcur->next;       //创建指针 n 为 pcur 指向的下一个结点
		free(pcur);                      //释放掉以遍历的队列结点
		pcur = n;                        //此时 pcur 等于下一个结点
	}
	//直到队列为空

	pq->phead = pq->ptail = NULL;
	pq->size = 0;

}
 

test.c

接下来可以再测试函数中测试代码中对队列的实现

#include"Queue.h"


void Queuetest()
{
	Queue q;
	QueueInit(&q);

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

	QueuePop(&q);
	

	int a = QueueFront(&q);
	int b = QueueBack(&q);
	printf("队头数据:%d\n", a);
	printf("队尾数据:%d\n", b);

	int c =QueueSize(&q);
	printf("有效数据个数:%d", c);

	QueueDestroy(&q);
}

int main()
{
	Queuetest();
	return 0;
}
  • 初始化 :

 

  •  入队:

 

  •  出队:

 

  • 最后结果:

未完待续~~

标签:结点,pq,队列,Queue,phead,数据结构,QueueNode
From: https://blog.csdn.net/2401_83968713/article/details/140560261

相关文章

  • 数据结构_排序
    目录一、排序二、插入排序2.1直接插入排序2.2希尔排序三、选择排序3.1直接选择排序3.2堆排序四、交换排序4.1冒泡排序4.2快速排序五、归并排序六、排序算法分析总结一、排序排序:就是使一串记录序列,按照其中某个或某些关键字的大小,进行递增或递减的排列......
  • [C++]优先级队列
    1.了解优先级队列优先级队列是一种容器适配器,根据一些严格的弱排序标准,专门设计使其第一个元素始终是它所包含的元素中最大的元素。此上下文类似于堆,其中可以随时插入元素,并且只能检索最大堆元素(优先级队列中顶部的元素)。优先级队列是作为容器适配器实现的,容器适配器是使......
  • 【数据结构】学习day 1.1线性表中的顺序表
    1 "&"区别(c++)#include<stdio.h>voidtest(intx){   x=2024;   printf("intestx=%d\n",x);}intmain(){   intx=1;   printf("beforetestx=%d\n",x);   test(x);   printf("aftertestx=%d\n"......
  • 数据结构——哈希
    前言顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较。顺序查找时间复杂度为O(N),平衡树中为树的高度,即O(logN),搜索的效率取决于搜索过程中元素的比价次数。理想的搜索方法:可以不经过任何比较,一次直接从表中得......
  • 顺序表实现队列(c语言)
    队列概念篇图示代码篇1.队列的声明2.队列的创建3.队列的销毁4.队列扩容5.入列6.出列6.队首元素7.队列的元素个数完整代码运行结果建议你在看这篇文章先看一下顺序表知识。我在这里通过顺序表的写法实现先进先出的特征来实现队列。当然顺序表也可以实现栈,感......
  • 数据结构—双向链表
    文章目录1.双向链表的概念和结构1.1双向链表的概念1.2双向链表与单链表的对比1.3双向链表的结构2.双向链表的接口实现2.1申请一个新结点2.2初始化2.3打印2.4尾插2.5头插2.6判断链表是否为空2.7尾删2.8头删2.9查找2.10在指定位置之后插入数据2.11在指定位......
  • 深入理解淘客返利系统中的异步消息处理与队列技术
    深入理解淘客返利系统中的异步消息处理与队列技术大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在现代的淘客返利系统中,高并发和复杂的业务需求要求我们采用异步消息处理和队列技术来提高系统的性能和可伸缩性。本文将深入探讨在淘客返利系统中如......
  • 使用Java和RabbitMQ构建消息队列系统
    使用Java和RabbitMQ构建消息队列系统大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!今天我们将深入探讨如何使用Java和RabbitMQ构建一个高效的消息队列系统。RabbitMQ是一个开源的消息中间件,支持多种消息协议,能够帮助我们实现异步处理和解耦。1.Rabbit......
  • 数据结构与算法 数组篇之长度最小的子数组
    问题描述:给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl,numsl+1,...,numsr-1,numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。题目链接:.-力扣(LeetCode)解题思路:双指针,......
  • 基础数据结构——初级——链表
    链表的特点是一组位于任意位置的存储单元存储线性表的数据元素。一般分为单向链表和双向链表(如下图所示)。 使用链表时,可以用STL的list,也可以自己写链表。如果自己写代码实现链表,有两种编码实现方法:动态链表和静态链表。在算法竞赛中为加快编码速度,一般用静态链表或者STL的l......