《队列》-C语言实现

本文主要使用C语言实现队列(尾插和头删)
在这里插入图片描述


前言

什们叫做队列

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

在这里插入图片描述


队列的实现

但是有人就会说,那是队列的话,尾插不也是很难吗?错了,我们可以定义一个头指针,一个尾指针,然后我们在尾插的时候我们直接用尾插就好了。

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低


创建工程文件还是三个文件

Queue.c,用来编写队列的函数内容
Queue.h用来包含函数的头文件
test.c用来测试函数。


(1)创建一个链式结构-表示队列

typedef int QDtataType;

//队列的链式结构
typedef struct QueueNode
{
	QDtataType data;
	struct QueueNode* next;
}QNode;

(2)队列的结构

我们队列包括,一个头和一个尾,来控制头插和尾插,还有一个sz知道队列的大小,我们要控制多个变量,我们就用结构体来控制,所以队列的结构如下。

//队列的结构
typedef struct Queue
{
	QNode*  front;
	QNode*  rear;
	int size;
}Queue;

这里的有点乱,我们画个图详细剖析一下
在这里插入图片描述

(3)队列的初始化

//队列的初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->front = pq->rear = NULL;
	pq->size = 0;
}

(4)队列的销毁

//队列销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->front;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->front = pq->rear = NULL;
	pq->size = 0;
}

(5)队列的插入<队尾入队列>

//队列的插入
//尾插
void QueuePush(Queue* pq, QDtataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;

	if (pq->rear == NULL)
	{
		pq->front = pq->rear = newnode;
	}
	else
	{
		pq->rear->next = newnode; //尾插
		pq->rear = newnode;//更新头的位置
	}
	pq->size++;
}

(6)判断队列是否为空

//队列的判空
int QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->front == NULL && pq->rear == NULL;
	//return pq->size == 0; //这样也行,但是,这个size是我们自己加到队列里面的,是为了方便求队列元素的个数
}

(7)队列的删除<队头出队列>

//队列的删除
//头删
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	if (pq->front->next == NULL)
	{
		free(pq->front);
		pq->front = pq->rear = NULL;
	}
	else
	{
		QNode* next = pq->front->next; //保存头的下一个
		free(pq->front);	//删除头
		pq->front = next;	//更新头
	}
	pq->size--;
}

(8)队列的大小

//队列的大小
int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

(9)取队头数据

//获取队头数据
QDtataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->front->data;
}

(10)取队尾数据

//获取队尾数据
QDtataType QueueRear(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->rear->data;
}

程序源码

Queue.h

#pragma once


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


typedef int QDtataType;

//队列的链式结构
typedef struct QueueNode
{
	QDtataType data;
	struct QueueNode* next;
}QNode;


//队列的结构
typedef struct Queue
{
	QNode*  front;
	QNode*  rear;
	int size;
}Queue;

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

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

//队列的插入
void QueuePush(Queue* pq, QDtataType x);


//队列的删除
void QueuePop(Queue* pq);

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

//队列的大小
int QueueSize(Queue* pq);

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

//获取队尾数据
QDtataType QueueRear(Queue* pq);


Queue.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "queue.h"

//队列的初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->front = pq->rear = NULL;
	pq->size = 0;
}


//队列销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->front;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->front = pq->rear = NULL;
	pq->size = 0;
}


//队列的插入
//尾插
void QueuePush(Queue* pq, QDtataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;

	if (pq->rear == NULL)
	{
		pq->front = pq->rear = newnode;
	}
	else
	{
		pq->rear->next = newnode; //尾插
		pq->rear = newnode;//更新头的位置
	}
	pq->size++;
}

//队列的判空
int QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->front == NULL && pq->rear == NULL;
	//return pq->size == 0; //这样也行,但是,这个size是我们自己加到队列里面的,是为了方便求队列元素的个数
}

//队列的删除
//头删
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	if (pq->front->next == NULL)
	{
		free(pq->front);
		pq->front = pq->rear = NULL;
	}
	else
	{
		QNode* next = pq->front->next; //保存头的下一个
		free(pq->front);	//删除头
		pq->front = next;	//更新头
	}
	pq->size--;
}

//队列的大小
int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

//获取队头数据
QDtataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->front->data;
}

//获取队尾数据
QDtataType QueueRear(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->rear->data;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "queue.h"




void test()
{
	Queue pq;
	QueueInit(&pq);
	QueuePush(&pq, 1);
	QueuePush(&pq, 2);
	QueuePush(&pq, 3);
	printf("size=%d\n", QueueSize(&pq));
	printf("%d\n", QueueFront(&pq));
	printf("%d\n", QueueRear(&pq));


	QueuePop(&pq);
	QueuePop(&pq);

	QueueDestroy(&pq);
}

int main()
{
	test();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值