【C语言】数据结构和算法->关于队列的使用

本次代码注释的很详细,需要解释的都在代码里了。

数据结构和算法->关于队列的使用

头文件:

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


typedef int DATATYPE;
typedef struct Queue
{
	struct Queue* next; //队列之间的元素使用指针连接起来
	DATATYPE data;
}Queue;

typedef struct QueuePointer
{
	//struct QueuePointer* head; //指向队列的第一个元素
	//struct QueuePointer* tail; //指向队列的最后一个元素
	Queue* head;
	Queue* tail;
}QP;

//队列的初始化
void QueueInit(QP* phead);

//队列的插入
void QueuePush(QP* phead, DATATYPE X); 

//队列的删除
void QueuePop(QP* phead);

//队列的输出
void QueuePrint(QP* phead);

//返回队列的队头的元素
DATATYPE QueueReturnFront(QP* phead);

//返回队列的队尾的元素
DATATYPE QueueRrturnBack(QP* phead);

//判断队列的元素个数
int QueueSize(QP* phead);

//判断队列是否为空
bool QueueEmpty(QP* phead);

//队列的销毁
void QueueDestroy(QP* phead);

源文件:

源文件包含两个,一个是主函数,程序的入口,包括函数的调用;另一个程序的执行代码,包括函数的定义。

#define _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"

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

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

void queueTest1()
{
	QP qp1;
	QueueInit(&qp1);

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

	QueuePrint(&qp1);

	QueuePop(&qp1);
	QueuePop(&qp1);
	QueuePop(&qp1);
	QueuePush(&qp1, 1);
	QueuePush(&qp1, 2);
	QueuePush(&qp1, 3);

	QueuePrint(&qp1);
	QueueDestroy(&qp1);
}

queueTest2()
{
	QP qp2;
	QueueInit(&qp2);

	QueuePush(&qp2, 10);
	QueuePush(&qp2, 20);
	QueuePush(&qp2, 30);
	QueuePush(&qp2, 40);

	QueuePrint(&qp2);

	DATATYPE temp = QueueReturnFront(&qp2);
	printf("队头的元素是%d\n", temp);
	
	DATATYPE ret = QueueRrturnBack(&qp2);
	printf("队尾的元素是%d\n", ret);

	if (QueueEmpty(&qp2))
	{
		printf("队列的大小是%d\n", QueueSize(&qp2));
	}
	else
	{
		printf("队列为空\n");
	}
	QueueDestroy(&qp2);
}

int main()
{
	
	queueTest1();
	queueTest2();
	return 0;
}

#define _CRT_SECURE_NO_WARNINGS 1

#include "Queue.h"

//队列的初始化
void QueueInit(QP* phead)
{
	assert(phead);
	phead->head = NULL;
	phead->tail = NULL;
}

//队列的插入
void QueuePush(QP* phead, DATATYPE X)
{
	assert(phead);

	Queue* NewNode = (Queue*)malloc(sizeof(Queue));
	if (NewNode == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	NewNode->data = X;
	NewNode->next = NULL;

	if (phead->tail == NULL)
	{
		phead->head = phead->tail = NewNode;
	}
	else
	{
		phead->tail->next = NewNode;
		phead->tail = NewNode;
	}
}

//队列的删除
void QueuePop(QP* phead)
{
	assert(phead);
	assert(phead->head); //

	if (phead->head->next == NULL)
	{
		free(phead->head);
		phead->head = NULL;
		phead->tail = NULL;
	}
	else
	{
		Queue* plist = phead->head->next;
		free(phead->head);
		phead->head = plist;
	}
}

//返回队列的队头的元素
DATATYPE QueueReturnFront(QP* phead)
{
	assert(phead);
	assert(phead->head);

	return phead->head->data;
}

//返回队列的队尾的元素
DATATYPE QueueRrturnBack(QP* phead)
{
	assert(phead);
	assert(phead->head);

	return phead->tail->data;
}

//判断队列的元素个数
int QueueSize(QP* phead)
{
	int count = 0; //一定要赋值,否则出现未定义行为

	Queue* ptr_queue = phead->head;
	while (ptr_queue)
	{
		count++;
		ptr_queue = ptr_queue->next;
	}
	return count;
}

//判断队列是否为空
bool QueueEmpty(QP* phead)
{
	return phead->head != NULL; //如果队列有元素,返回真,否则,返回假
}

//队列的输出
void QueuePrint(QP* phead)
{
	Queue* plist = phead->head;
	while (plist)
	{
		//printf("%d->", phead->head->data);
		phead->head++; 链表的地址是不连续的
		//phead->head = phead->head->next;//不要这样书写,这样改变了头指针的位置,会导致在调用的时候引起其他函数出现问题
		printf("%d->", plist->data);
		plist = plist->next;
	}
	printf("\n");
}

//队列的销毁
void QueueDestroy(QP* phead)
{
	assert(phead);
	//assert(phead->head); phead->head = NULL就表明目前没有开辟的内存空间,这里不需要断言
	Queue* plist = phead->head;
	while (plist)
	{
		//第一种写法:
		//Queue* slist = plist->next;
		Queue* slist = phead->head->next; //这样写是不行的,因为slist的位置没有改变
		//free(plist);
		//plist = slist->next;
		
		//第二种写法:
		plist = plist->next;
		free(phead->head);
		phead->head = plist;
	}
	phead->head = phead->tail = NULL;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值