栈和队列

文章详细介绍了如何使用C语言实现链式队列的数据结构,包括队列的概念、构造、初始化、销毁、在队尾插入数据、从队头删除数据、获取队列大小和判断队列是否为空以及返回队首和队尾数据等操作。并通过测试代码展示了在VisualStudio上的运行过程。
摘要由CSDN通过智能技术生成

目录

1.1 队列的概念及结构

1.2 构造队列

1.3 初始化队列

1.4 毁坏队列的所有节点

 1.5 在队尾插入数据

 1.6 在队头删除数据

1.7 返回队列的节点数、判断队列是否为空

1.8 返回队首数据和队尾数据

1.9 运行测试(在Visual Studio上运行)


1.1 队列的概念及结构

只允许在一端进行插入数据操作,而在另一端进行删除数据操作的特殊的线性表,队列具有先进先出的特性。

入队列:进行插入数据操作的一端叫做队尾。

出队列:进行删除数据操作的一端叫做队头。

结构示意图如下:

1.2 构造队列

通过链式结构表示队列

typedef int QDataType;
//链式结构:表示队列
typedef struct QueueNode {
	QueueNode* next;
	QDataType data;
}QNode;

 由于队列需要在队头和队尾两端进行不同的操作,所以队列本身应包含队头和队尾。

此时,构造队列的结构

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

1.3 初始化队列

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

1.4 毁坏队列的所有节点

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

此处需要注意:构成队列的节点的结构体是QNode, 表明队列性质(即队头删除、队尾插入)的结构体(head、tail、size)是Queue。

如下图所示:

 1.5 在队尾插入数据

void QPush(Queue* pq, QDataType x) {
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode = NULL) {
		perror("malloc fail");
		return;
	}
	//为新节点赋值x
	newnode->data = x;
	newnode->next = NULL;
	//将新节点链接到队尾
	if (pq->head == NULL) {
		pq->head = pq->tail = newnode;
	}
	else {
		pq->tail->next = newnode;
		pq->tail = pq->tail->next;
	}
    pq->size++;
}

 1.6 在队头删除数据

void QPop(Queue* pq) {
	//进行断言
	assert(pq);
		//删除时头不能为空
	assert(pq->head != NULL);
	//进行删除
	QNode* hnext = pq->head->next;
		//首先,若只剩下一个节点时:
	if (hnext == NULL) {
		pq->head = pq->tail = NULL;
	}
	else {
		free(pq->head);
		pq->head = hnext;
	}
	pq->size--;
}

1.7 返回队列的节点数、判断队列是否为空

int QSize(Queue* pq) {
	assert(pq);
	return pq->size;
}
bool QEmpty(Queue* pq) {
	assert(pq);
	return pq->size == 0;
}

1.8 返回队首数据和队尾数据

QDataType QFront(Queue* pq) {
	assert(pq);
	assert(!QEmpty(pq));
	return pq->head->data;
}
QDataType QBack(Queue* pq) {
	assert(pq);
	assert(!QEmpty(pq));
	return pq->tail->data;
}

1.9 运行测试(在Visual Studio上运行)

头文件(Queue.h)

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

typedef int QDataType;
//链式结构:表示队列
typedef struct QueueNode {
	struct QueueNode* next;
	QDataType data;
}QNode;
//队列的结构
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

void QInit(Queue* pq);
void QDestroy(Queue* pq);
void QPush(Queue* pq,QDataType x);
void QPop(Queue* pq);
int QSize(Queue* pq);
bool QEmpty(Queue* pq);
QDataType QFront(Queue* pq);
QDataType QBack(Queue* pq);

源文件1(Queue.c)

#include"Queue.h"
void QInit(Queue* pq) {
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
void QDestroy(Queue* pq) {
	assert(pq);
	QNode* cur = pq->head;
	while (cur) {
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
void QPush(Queue* pq, QDataType x) {
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL) {
		perror("malloc fail");
		return;
	}
	//为新节点赋值x
	newnode->data = x;
	newnode->next = NULL;
	//将新节点链接到队尾
	if (pq->head == NULL) {
		pq->head = pq->tail = newnode;
	}
	else {
		pq->tail->next = newnode;
		pq->tail = pq->tail->next;
	}
	pq->size++;

}
void QPop(Queue* pq) {
	//进行断言
	assert(pq);
		//删除时头不能为空
	assert(pq->head != NULL);
	//进行删除
	QNode* hnext = pq->head->next;
		//首先,若只剩下一个节点时:
	if (hnext == NULL) {
		pq->head = pq->tail = NULL;
	}
	else {
		free(pq->head);
		pq->head = hnext;
	}
	pq->size--;
}
int QSize(Queue* pq) {
	assert(pq);
	return pq->size;
}
bool QEmpty(Queue* pq) {
	assert(pq);
	return pq->size == 0;
}
QDataType QFront(Queue* pq) {
	assert(pq);
	assert(!QEmpty(pq));
	return pq->head->data;
}
QDataType QBack(Queue* pq) {
	assert(pq);
	assert(!QEmpty(pq));
	return pq->tail->data;

源文件2(Test.c)

#include"Queue.h"
int main() {
	Queue p;
	QInit(&p);
	QPush(&p, 1);
	QPush(&p, 2);
	QPush(&p, 3);
	QPush(&p, 4);
	while (!QEmpty(&p)) {
		printf("%d ", QFront(&p));
		QPop(&p);
	}
	printf("\n");
	QDestroy(&p);
	return 0;
}

运行结果:

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值