数据结构队列实现(赋完整代码)

发布时间:2024年01月15日


1、定义及结构

1.一种特殊的线性表,只允许在一段进行插入,另一段进行删除;

2.进行插入操作的一端称为队尾,进行删除操作的一端称为队头;

3.队列具有先进先出的特性 FIFO(First In First Out)

在这里插入图片描述

队列总体来说是现实生活中的排队取号类似,先取票的,就先办理业务;队列中,先进入的,就先出去

2、队列实现

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列类似顺序表头删数据,效率会比较低;此处我们就以链表结构实现队列举例:

1)结构定义:队列中我们在对头位置处队,对尾位置入队。为了便于操作,我们新建的一个结构体,用于存放队头、对尾位置的地址以及队中的数据个数。

typedef struct QueueNode {
	QNDataType val;//数据域
	struct QueueNode* next;//指针域
}QN;

typedef struct Queue {
	QN* head;//头
	QN* tail;//尾
	int size;//有效数据个数,便于统计个数
}Queue;

2)初始化

// 初始化队列 
void QueueInit(Queue* q) {
	assert(q);
	//初始队中无元素,队头、队尾都置为NULL
	q->head = q->tail = NULL;
	q->size = 0;
}

3)入队

// 入队
void QueuePush(Queue* q, QNDataType data) {
	assert(q);

	//创建新节点
	QN* newNode = (QN*)malloc(sizeof(QN));
	newNode->next = NULL;
	newNode->val = data;
	if (newNode == NULL) {
		perror("malloc");
	}

	//第一个节点,要对头位置进行修改
	if (q->head == NULL) {
		q->head = q->tail = newNode;
	}
	//其余位置都支对尾位置进行修改即可
	else {
		q->tail->next = newNode;
		q->tail = newNode;
	}

	//有效数据个数加一
	q->size++;
}

4)出队

//出队
void QueuePop(Queue* q) {
	assert(q);

	//判空
	assert(q->head);

	//仅有一个节点
	if (q->head->next == NULL) {
		free(q->head);
		q->head = NULL;
	}
	//有两个或以上节点
	else {
		QN* next = q->head->next;
		free(q->head);
		q->head = NULL;

		q->head = next;
	}

	q->size--;
}

5)获取队头元素

// 获取队列头部元素 
QNDataType QueueFront(Queue* q) {
	assert(q);
	assert(q->head);

	return q->head->val;
}

6)获取队尾元素

// 获取队列队尾元素 
QNDataType QueueBack(Queue* q) {
	assert(q);
	assert(q->head);

	return q->tail->val;
}

7)获取队列中元素个数

// 获取队列中有效元素个数 
int QueueSize(Queue* q) {
	assert(q);

	return q->size;
}

8)队列判空

// 检测队列是否为空
bool QueueEmpty(Queue* q) {
	assert(q);

	return q->head == NULL;
}

9)清空队列

//清空队列
void QueueClear(Queue* q) {
	assert(q);
	assert(q->head);
	//将队列中除首元素节点外的节点释放
	QN* t = q->head->next;
	while (t) {
		QN* next = t->next;
		free(t);
		t = NULL;

		t = next;
	}

	//将头和尾节点置为NULL
	q->head = q->tail = NULL;
}

10)销毁队列

// 销毁队列 
void QueueDestroy(Queue* q) {
	assert(q);

	//将队列中所有空间释放
	while (q->head) {
		QN* next = q->head->next;
		free(q->head);
		q->head = NULL;

		q->head = next;
	}
	q->size = 0;
}

完整代码

1.Queue.h

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

typedef int QNDataType;

typedef struct QueueNode {
	QNDataType val;//数据域
	struct QueueNode* next;//指针域
}QN;

typedef struct Queue {
	QN* head;//头
	QN* tail;//尾
	int size;//有效数据个数,便于统计个数
}Queue;

// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QNDataType data);
// 队头出队列 
void QueuePop(Queue* q);
// 获取队列头部元素 
QNDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QNDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空
bool QueueEmpty(Queue* q);
//清空
void QueueClear(Queue*q);
// 销毁队列 
void QueueDestroy(Queue* q);

2.Queue.c

#pragma once
#include"Queue.h"

// 初始化队列 
void QueueInit(Queue* q) {
	assert(q);
	//初始队中无元素,队头、队尾都置为NULL
	q->head = q->tail = NULL;
	q->size = 0;
}

// 入队
void QueuePush(Queue* q, QNDataType data) {
	assert(q);

	//创建新节点
	QN* newNode = (QN*)malloc(sizeof(QN));
	newNode->next = NULL;
	newNode->val = data;
	if (newNode == NULL) {
		perror("malloc");
	}

	//第一个节点,要对头位置进行修改
	if (q->head == NULL) {
		q->head = q->tail = newNode;
	}
	//其余位置都支对尾位置进行修改即可
	else {
		q->tail->next = newNode;
		q->tail = newNode;
	}

	//有效数据个数加一
	q->size++;
}

//出队
void QueuePop(Queue* q) {
	assert(q);

	//判空
	assert(q->head);

	//仅有一个节点
	if (q->head->next == NULL) {
		free(q->head);
		q->head = NULL;
	}
	//有两个或以上节点
	else {
		QN* next = q->head->next;
		free(q->head);
		q->head = NULL;

		q->head = next;
	}

	q->size--;
}

// 获取队列头部元素 
QNDataType QueueFront(Queue* q) {
	assert(q);
	assert(q->head);

	return q->head->val;
}

// 获取队列队尾元素 
QNDataType QueueBack(Queue* q) {
	assert(q);
	assert(q->head);

	return q->tail->val;
}

// 获取队列中有效元素个数 
int QueueSize(Queue* q) {
	assert(q);

	return q->size;
}

// 检测队列是否为空
bool QueueEmpty(Queue* q) {
	assert(q);

	return q->head == NULL;
}

//清空队列
void QueueClear(Queue* q) {
	assert(q);
	assert(q->head);
	//将队列中除首元素节点外的节点释放
	QN* t = q->head->next;
	while (t) {
		QN* next = t->next;
		free(t);
		t = NULL;

		t = next;
	}

	//将头和尾节点置为NULL
	q->head = q->tail = NULL;
}

// 销毁队列 
void QueueDestroy(Queue* q) {
	assert(q);

	//将队列中所有空间释放
	while (q->head) {
		QN* next = q->head->next;
		free(q->head);
		q->head = NULL;

		q->head = next;
	}
	q->size = 0;
}

3.Test.c

#define _CRT_SECURE_NO_WARNINGS
#include"Queue.h"

int main() {

	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 4);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePop(&q);
	int head = QueueFront(&q);
	printf("%d\n",head);
	int end = QueueBack(&q);
	printf("%d\n",end);
	int size = QueueSize(&q);
	printf("%d\n",size);
	bool ret1 = QueueEmpty(&q);
	if (ret1 == true) {
		printf("空\n");
	}
	else {
		printf("非空\n");
	}
	QueueClear(&q);

	bool ret2 = QueueEmpty(&q);
	if (ret2 == true) {
		printf("空\n");
	}
	else {
		printf("非空\n");
	}

	QueueDestroy(&q);

	return 0;
}
文章来源:https://blog.csdn.net/wjfwonderful/article/details/135603303
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。