链表形式队列

🌈队列相关概念

1.储存了数据的节点从一端(队尾)进入队列(入队尾插),从另一端(队头)出队列(出队头删),先进先出。进行插入操作的一端称为队尾,进行进行删除操作的一端称为队头。

2.用途:由于先进先出的功能,链队列可以用来历史重演,如排队叫号(先到的人先被叫到)。(栈结构由于后进先出的功能,可以用来历史的回溯,比如撤销上一秒操作的内容)

🌈链队列基础框架

🎈Queue.h定义声明

c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int DataType;
typedef struct Node {
	DataType data;
	struct Node* next;
}Node;
typedef struct Queue {
	Node* head;
	Node* tail;
	int size;
}Queue;

void InitQueue(Queue* pq);
void Destroy(Queue* pq);
void Push(Queue* pq, DataType x);
void Pop(Queue* pq);
DataType Front(Queue* pq);
void Display(Queue* pq);

🎈Queue.c函数实现

☀️初始化:InitQueue()

c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include"Queue.h"
void InitQueue(Queue* pq) {
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

☀️销毁:Destroy()

c 复制代码
void Destroy(Queue* pq) {
	assert(pq);
	if (pq->head) {
		Node* cur = pq->head->next;
		while (cur) {
			Node* next = cur->next;
			free(cur);
			cur = next;
		}
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

☀️入队:Push()

c 复制代码
void Push(Queue* pq, DataType x) {
	assert(pq);
	Node* newnode = (Node*)malloc(sizeof(Node));
	newnode->data = x;
	newnode->next = NULL;
	if (!newnode) {
		perror("malloc fail");
		exit(-1);
	}
	//首次入队
	if (pq->tail == NULL) {
		pq->head = pq->tail = newnode;
	}
	//非首次入队,对头是有元素的
	else {
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}

☀️出队:Pop()

c 复制代码
void Pop(Queue* pq) {
	assert(pq);
	//当头指针与尾指针重合,说明队内只剩一个元素,该元素出队后,队列回到初始化状态(头尾指针都为空)
	if (pq->head == pq->tail) {
		pq->head = pq->tail = NULL;
	}
	else {
		Node* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	pq->size--;
}

☀️得到队头元素:Front()

c 复制代码
DataType Front(Queue* pq) {
	assert(pq);
	assert(pq->tail);
	return pq->head->data;
}

☀️打印整个队列:Display()

c 复制代码
void Display(Queue* pq) {
	assert(pq);
	Node* cur = pq->head;
	while (cur) {
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL");
}

🎈test.c主函数,测试

c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include"Queue.h"
int main() {
	Queue Q;
	InitQueue(&Q);

	DataType data = 1;
	Push(&Q, data);
	data = 2;
	Push(&Q, data);
	data = 3;
	Push(&Q, data);
	data = 4;
	Push(&Q, data);
	Display(&Q);
	printf("\n");

	DataType del = Front(&Q);
	Pop(&Q);
	Display(&Q);
	printf(" 出队元素是%d\n", del);
	del = Front(&Q);
	Pop(&Q);
	Display(&Q);
	printf(" 出队元素是%d\n", del);
	del = Front(&Q);
	Pop(&Q);
	Display(&Q);
	printf(" 出队元素是%d\n", del);
	del = Front(&Q);
	Pop(&Q);
	Display(&Q);
	printf(" 出队元素是%d\n", del);

	Destroy(&Q);
}

☀️测试运行结果:

🌈用链队列形式实现学生信息的入队与出队

🎈Queue.h定义声明

c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef struct student {
	int age;
	int height;
	double weight;
}Student;
typedef struct Node {
	Student stu;
	struct Node* next;
}Node;
typedef struct Queue {
	Node* head;
	Node* tail;
	int size;
}Queue;

void InitQueue(Queue* pq);
void Destroy(Queue* pq);
void GetVal(Student* stu);
Node* CreateNode(Student* stu);
void Push(Queue* pq, Student* stu);
void Pop(Queue* pq);
void PrintNode(Student* stu);
void Display(Queue* pq);

🎈Queue.c函数实现

c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include"Queue.h"
void InitQueue(Queue* pq) {
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

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

void GetVal(Student* stu) {
	printf("请输入学生年龄、身高、体重:");
	scanf("%d %d %lf", &stu->age, &stu->height, &stu->weight);
}

Node* CreateNode(Student* stu) {
	GetVal(stu);
	Node* newnode = (Node*)malloc(sizeof(Node));
	if (!newnode) {
		perror("malloc fail");
		exit(-1);
	}
	newnode->stu.age = stu->age;
	newnode->stu.height = stu->height;
	newnode->stu.weight = stu->weight;
	//newnode->stu = *stu;
	newnode->next = NULL;
	return newnode;
}

void Push(Queue* pq, Student* stu) {
	assert(pq);
	Node* newnode = CreateNode(stu);
	if (pq->tail == NULL) {
		pq->head = pq->tail = newnode;
	}
	else {
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}

void Pop(Queue* pq) {
	assert(pq);
	if (!pq->head)return;
	else if (pq->head == pq->tail) {
		pq->head = pq->tail = NULL;
		pq->size = 0;
	}
	else{
		Node* newhead = pq->head->next;
		free(pq->head);
		pq->head = newhead;
		pq->size--;
	}
}

void PrintNode(Student* stu) {
	assert(stu);
	printf("年龄:%-5d 身高:%-5d 体重:%-5lf", stu->age, stu->height, stu->weight);
}

void Display(Queue* pq) {
	assert(pq);
	Node* cur = pq->head;
	if (!cur)printf("队列中无信息\n");
	while (cur) {
		PrintNode(&cur->stu);
		printf("\n");
		cur = cur->next;
	}
}

🎈test.c主函数,测试

c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include"Queue.h"
int main() {
	Queue Q;
	InitQueue(&Q);
	Student stu;
	Push(&Q, &stu);
	Push(&Q, &stu);
	Push(&Q, &stu);
	Display(&Q);

	Student del = Q.head->stu;
	Pop(&Q);
	printf("出队的一组数据是:");
	PrintNode(&del);
	printf("\n");
	del = Q.head->stu;
	Pop(&Q);
	printf("出队的一组数据是:");
	PrintNode(&del);
	printf("\n");
	del = Q.head->stu;
	Pop(&Q);
	printf("出队的一组数据是:");
	PrintNode(&del);
	printf("\n");

	Destroy(&Q);
}

🎈测试运行结果:

注意:scanf的占位符只能写类似"%d %lf"等等,不能写"%-5d",否则会导致数据存储不到目的空间,并且数据与数据间用什么符号隔开,在输入数据时就要严格用同样符号隔开。只有在使用printf函数并且需要调整数据打印出的位置时才用类似"%-5d"。以下是scanf占位符书写有误时的运行结果:

相关推荐
再睡一夏就好12 分钟前
【C++闯关笔记】STL:deque与priority_queue的学习和使用
java·数据结构·c++·笔记·学习·
Yeats_Liao16 分钟前
Go Web 编程快速入门 01 - 环境准备与第一个 Web 应用
开发语言·前端·golang
卓码软件测评16 分钟前
第三方CMA软件测试机构:页面JavaScript动态渲染生成内容对网站SEO的影响
开发语言·前端·javascript·ecmascript
*才华有限公司*21 分钟前
《爬虫进阶之路:从模拟浏览器到破解动态加载的实战指南》
开发语言·python
敲代码的嘎仔40 分钟前
JavaWeb零基础学习Day4——Maven
java·开发语言·学习·算法·maven·javaweb·学习方法
遇印记42 分钟前
网络运维学习笔记
数据结构·笔记·学习
W.Buffer1 小时前
设计模式-工厂模式:解耦对象创建的设计艺术
java·开发语言·设计模式
梵得儿SHI1 小时前
Java 注解与反射实战:自定义注解从入门到精通
java·开发语言·注解·自定义注解·元注解·控制注解的作用·声明式编程思想
沐知全栈开发1 小时前
Foundation 网格实例
开发语言
_dindong1 小时前
牛客101:链表
数据结构·c++·笔记·学习·算法·链表