C语言 学生类型队列的基本操作和详细代码

队列的概念及结构:

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

队列的作用:

队列主要是运用于任务调度和消息传递等一些场景当中,在很多地方都会有队列的身影,所有学习队列是有必要的。

源码:

好了,废话不多说,直接上源码!!!

.h文件,主要是创建了一些学生信息和列表以及结点相关结构体。

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#ifndef _STU_H
#define _STU_H

typedef struct
{
	int num;
	char name[10];
}Student;

//队列结构体
/*
StuQListNode---------结构体标签
Stu_Node-------------结构体类型
*/
typedef struct StuQListNode
{
	struct StuQListNode* next;//指向下一个节点指针
	Student data;//节点数据
}Stu_Node;


typedef struct 
{
	Stu_Node* front;//头指针
	Stu_Node* rear;//尾指针
}Stu_Queue;


void Stu_Queue_Init(Stu_Queue* q);
void Queue_Pop_Add(Stu_Queue* q, int stu_num, const char* stu_name);
void Queue_Push_Add(Stu_Queue* q, int stu_num, const char* stu_name);
void Queue_Stu_Del(Stu_Queue* q, int stu_num);
void Queue_Stu_Updata(Stu_Queue* q, int stu_num, int new_num, const char* new_name);
void Queue_Stu_find(Stu_Queue* q, int stu_num);
void find_all(Stu_Queue* q);
void Queue_roll(Stu_Queue* q);
void adjacent_node(Stu_Queue* q, int stu_num1, int stu_num2);
int Queue_sum(Stu_Queue* q);


#endif // !_STU_H

.c文件,主要是实现了一些学生信息队列的基本操作,包括增删改查,结点翻转,相邻结点交换位置,计算队列结点数量的一些操作。

#include "main.h"



//创建节点
Stu_Node* Create_Node(int stu_num, const char* stu_name)
{
	Stu_Node* node = (Stu_Node*)malloc(sizeof(Stu_Node));
	if (node != NULL)
	{
        node->data.num = stu_num;
		strncpy(node->data.name, stu_name, sizeof(node->data.name) - 1);
		node->data.name[sizeof(node->data.name) - 1] = '\0';  // 确保字符串以 null 结尾
		node->next = NULL;
	}

	return node;
}

//初始化队列
void Stu_Queue_Init(Stu_Queue* q)
{
	q->front = NULL;
	q->rear = NULL;
}

//头部增加数据
void Queue_Pop_Add(Stu_Queue* q, int stu_num, const char* stu_name)
{
	Stu_Node* node = Create_Node(stu_num, stu_name);
	if (q->front == NULL)
	{
		q->front = q->rear = node;
	}
	else 
	{
		node->next = q->front;
		q->front = node;
	}
}

//尾部增加数据
void Queue_Push_Add(Stu_Queue* q, int stu_num, const char* stu_name)
{
	Stu_Node* node = Create_Node(stu_num, stu_name);
	if (q->front == NULL)
	{
		q->front = q->rear = node;
	}
	else
	{
		q->rear->next = node;
		q->rear = node;
	}
}

//删除节点
void Queue_Stu_Del(Stu_Queue* q, int stu_num)
{
	Stu_Node* node = q->front;
	Stu_Node* node_data = NULL;
	// 查找包含指定学号的节点
	while (node != NULL && node->data.num != stu_num)
	{
		node_data = node;
		node = node->next;
	}
	if (node != NULL)
	{
		// 检查是否是头节点或尾节点
		if (node_data != NULL)
		{
			node_data->next = node->next;
		}
		else q->front = node->next;
		if (node == q->rear) q->rear = node_data;

		free(node);
	}
	else printf("Not found\n");
}

//修改节点数据
void Queue_Stu_Updata(Stu_Queue* q,int stu_num,int new_num,const char* new_name)
{
	Stu_Node* node = q->front;
	while (node != NULL && node->data.num != stu_num)
	{
		node = node->next;
	}
	if (node != NULL)
	{
		node->data.num = new_num;
		strcpy(node->data.name, new_name);
	}
	else printf("not found\n");
}

//查找某个节点数据
void Queue_Stu_find(Stu_Queue* q, int stu_num)
{
	Stu_Node* node = q->front;
	while (node != NULL && node->data.num != stu_num)
	{
		node = node->next;
	}
	if (node != NULL)
	{
		printf("ID:%d  NAME:%s\n", node->data.num, node->data.name);
	}
	else printf("not found\n");
}

//打印所有节点
void find_all(Stu_Queue* q)
{
	if (q->front==NULL)
	{
		printf("No data\n");
		return;
	}

	Stu_Node* node = q->front;
	while (node != NULL)
	{
		printf("ID:%d  NAME:%s\n", node->data.num, node->data.name);
		node = node->next;
	}
}

//队列翻转
void Queue_roll(Stu_Queue* q) 
{
	Stu_Node* stack = NULL;        //创建一个指向`Stu_Node结构体的指针,用于构建一个栈,该栈将帮助我们翻转队列中的元素。
	Stu_Node* current = q->front;  //创建一个指向当前队列头部的指针。

	//当队列不为空时执行以下循环-----入栈
	while (current != NULL) 
	{
		Stu_Node* next = current->next; //保存当前节点的下一个节点。
		current->next = stack;          //将当前节点的`next`指针指向栈的顶部,实现入栈操作。
		stack = current;                //将栈的顶部指针指向当前节点,更新栈的顶部。
		current = next;                 //移动到下一个节点。
	}

	q->front = stack;       //更新队列的头指针为栈的顶部,即反转后的队列的头。
	q->rear = q->front;     //更新队列的尾指针为队列的头指针,因为栈是从头到尾反转的。

	//当栈不为空时执行以下循环-----出栈
	while (stack != NULL) 
	{
		if (stack->next == NULL) //如果栈的下一个节点为空,即栈的底部。
		{
			q->rear = stack;    //更新队列的尾指针为栈的底部,即反转后的队列的尾。
		}
		stack = stack->next;   //移动到栈的下一个节点。
	}
}

//相邻两个节点交换数据
void adjacent_node(Stu_Queue* q, int stu_num1, int stu_num2)
{
	Stu_Node* node1 = q->front;
	Stu_Node* node2 = q->front;
	Stu_Node* per1 = NULL;
	Stu_Node* per2 = NULL;
	while (node1 != NULL && node1->data.num != stu_num1)
	{
		per1 = node1;
		node1 = node1->next;
	}
	while (node2 != NULL && node2->data.num != stu_num2)
	{
		per2 = node2;
		node2 = node2->next;
	}
	if (node1 != NULL && node2 != NULL)
	{
		//判断是否是相邻的位置
		if (node1->next == node2)//node1在前
		{
			Stu_Node* node = node2->next;
			//判断是否处于头结点
			if (per1 != NULL) per1->next = node2;
			else q->front = node2;

			node2->next = node1;
			node1->next = node;
		}
		else if (node2->next == node1)//node2在后
		{
			Stu_Node* node = node1->next;
			//判断是否处于头结点
			if (per2 != NULL) per2->next = node1;
			else q->front = node1;

			node1->next = node2;
			node2->next = node;
		}
		else printf("两个数据不是相邻数据\n");
	}
	else printf("not found\n");
}

//计算队列中结点个数
int Queue_sum(Stu_Queue* q)
{
	Stu_Node* node = q->front;
	int count = 0;
	while (node != NULL)
	{
		count++;
        if (node == q->rear) break;
		node = node->next;
	}
	return count;
}

在看看mian.c里面测试的函数把!!!

#include "main.h"




int main() 
{
	Stu_Queue q;
	Stu_Queue_Init(&q);
	Queue_Push_Add(&q, 407, "张三");
	Queue_Push_Add(&q, 408, "李四");
	Queue_Push_Add(&q, 409, "王五");
	Queue_Push_Add(&q, 410, "李二");
	Queue_Push_Add(&q, 411, "麻子");

	//删除某个结点
	/*Queue_Stu_Del(&q, 410);*/

	//修改某个结点
	/*Queue_Stu_Updata(&q, 409, 412, "谢有源");*/

	//寻找某个结点
	/*Queue_Stu_find(&q, 409);*/

	//将整个队列进行倒序
	/*Queue_roll(&q);*/

	//交换相邻位置的结点
	/*adjacent_node(&q, 411, 410);*/

	//查询队列结点数
	/*printf("num=%d\n", Queue_sum(&q));*/

	//打印队列全部成员
	find_all(&q);

    return 0;
}

 再看看测试结果,也是成功的创建了学生列表和插入。

 为了防止部分初学者找不到一些函数的头文件,我在这里把mian.h里面的头文件也提供出来把!

#define _CRT_SECURE_NO_WARNINGS   //用于strncpy函数
#pragma once
#ifndef _MAIN_H
#define _MAIN_H

//库头文件
#include <stdio.h>
#include "malloc.h"
#include "string.h"


//.c头文件
#include "test.h"
#include "stu.h"


#endif // !_MAIN_H

好了,以前就是学生列表的一些基本操作,仅供参考学习,大家也可以根据学生信息的不同,修改学生信息结构的内容,在此祝大家一帆风顺!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值