植物大战 队列 —— 纯C

这里是目录

  • 队列的实现
    • 基本概念
    • 创建结构体
    • 初始化结构体
    • 销毁队列结构体
    • 入队
    • 出队
    • 判断队列是否为空
    • 访问对头的值
    • 访问队尾的值
    • 返回队列的长度
    • Queue.h
    • Queue.c
    • Test.c

队列的实现

基本概念

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出
FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头
在这里插入图片描述队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低需要挪动数据O(N)。而链表结构头删只需要O(1)。尾插定义一个尾指针,也只需要O(1)。
在这里插入图片描述

创建结构体

这是一个嵌套结构体。
实参q的地址传给了形参pq。pq就是一个指向结构体Queue的指针。Queue里面的head是指向队列对头的指针,tail是指向队尾的指针。

在这里插入图片描述

int main(){//创建结构体变量q//需要传q的地址过去。	Queue q;	return 0;}

定义一个尾指针tail方便入队的尾插。头指针head方便出队时的头删。

typedef int QDataType;//节点结构体typedef struct QueueNode{	QDataType data;	struct QueueNode* next;}QNode;//头指针和尾指针的结构体typedef struct Queue{	QNode* head;	QNode* tail;}Queue;

初始化结构体

才开始还没有创建队列的空间,所以只需要初始化第一个结构体就ok了。
队列初始状态需要对头和队尾指向同一位置,且都是空。

void QueueInit(Queue* pq){	assert(pq);	pq->head = pq->tail = NULL;}

销毁队列结构体

这次我把销毁结构体放在初始化结构体的后面,原因是内存泄漏很严重,但是经常会忘记销毁结构体。创建意味着就要销毁,二者对立,所以排在初始化的后面,理所应当。

void QueueDestory(Queue* pq){	assert(pq);	QNode* cur = pq->head;	while (cur)	{		QNode* next = cur->next;		free(cur);		cur = next;	}	pq->head = pq->tail = NULL;}

入队

入队的时候,会创建新的节点。最好最好把新开的newnode节点初始化。把他的next置为空,方便后期求队列长度函数,和出队函数的循环条件的书写。

void QueuePush(Queue* pq, QDataType x){	assert(pq);	QNode* newnode = (QNode*)malloc(sizeof(QNode));	assert(newnode);	//下面两个初始化很有必要	newnode->data = x;	newnode->next = NULL;	if (pq->tail == NULL)	{		assert(pq->head == NULL);		pq->head = pq->tail = newnode;	}	else	{		pq->tail->next = newnode;		pq->tail = newnode;	}}

出队

因为Queue结构体不可能为空,所以需要断言
还需要断言pq->head和tail都不为空。

void QueuePop(Queue* pq){	assert(pq);	assert(pq->head && pq->tail);	if (pq->head->next == NULL)	{		free(pq->head);		pq->head = pq->tail = NULL;	}	else	{		QNode* next = pq->head->next;		free(pq->head);		pq->head = next;	}}

判断队列是否为空

为空返回true,为假返回false

bool QueueEmpty(Queue* pq){	assert(pq);	return pq->head == NULL;}

访问对头的值

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

访问队尾的值

QDataType QueueBack(Queue* pq){	assert(pq);	assert(pq->tail);	return pq->tail->data;}

返回队列的长度

长度不可能为负数,所以返回类型为size_t

size_t QueueSize(Queue* pq){	assert(pq);	QNode* cur = pq->head;	size_t size = 0;	while (cur)	{		size++;		cur = cur->next;	}	return size;}

Queue.h

#pragma once#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#include <assert.h>typedef int QDataType;typedef struct QueueNode{	QDataType data;	struct QueueNode* next;}QNode;typedef struct Queue{	QNode* head;	QNode* tail;	//size_t size;}Queue;void QueueInit(Queue* pq);void QueueDestory(Queue* pq);void QueuePush(Queue* pq, QDataType x);void QueuePop(Queue* pq);bool QueueEmpty(Queue* pq);size_t QueueSize(Queue* pq);QDataType QueueFront(Queue* pq);QDataType QueueBack(Queue* pq);

Queue.c

#include "Queue.h"void QueueInit(Queue* pq){	assert(pq);	pq->head = pq->tail = NULL;}void QueueDestory(Queue* pq){	assert(pq);	QNode* cur = pq->head;	while (cur)	{		QNode* next = cur->next;		free(cur);		cur = next;	}	pq->head = pq->tail = NULL;}void QueuePush(Queue* pq, QDataType x){	assert(pq);	QNode* newnode = (QNode*)malloc(sizeof(QNode));	assert(newnode);	newnode->data = x;	newnode->next = NULL;	if (pq->tail == NULL)	{		assert(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 && pq->tail);	if (pq->head->next == NULL)	{		free(pq->head);		pq->head = pq->tail = NULL;	}	else	{		QNode* next = pq->head->next;		free(pq->head);		pq->head = next;	}}bool QueueEmpty(Queue* pq){	assert(pq);	return pq->head == NULL;}size_t QueueSize(Queue* pq){	assert(pq);	QNode* cur = pq->head;	size_t size = 0;	while (cur)	{		size++;		cur = cur->next;	}	return size;}QDataType QueueFront(Queue* pq){	assert(pq);	assert(pq->head);	return pq->head->data;}QDataType QueueBack(Queue* pq){	assert(pq);	assert(pq->tail);	return pq->tail->data;}

Test.c

void TestQueue(){	Queue q;	QueueInit(&q);	QueuePush(&q, 1);	QueuePush(&q, 2);	printf("%d ", QueueFront(&q));	QueuePop(&q);	QueuePush(&q, 3);	QueuePush(&q, 4);	while (!QueueEmpty(&q))	{		printf("%d ", QueueFront(&q));		QueuePop(&q);	}	printf("n");}int main(){	TestQueue();	return 0;}
 
友情链接
鄂ICP备19019357号-22