C语言数据结构--队列

基本概念

队列是一种 先进先出(FIFO)的线性表
顾名思义,就和排队一样,先加入队伍的人先离开队伍,后加入队伍的人后离开队伍
队列只允许在队尾插入元素,在队头删除元素
在这里插入图片描述
既然队列是线性表的一种,那么肯定也有两种存储形式
链队列 ——链式映像
循环队列——顺序映像

栈一般使用顺序表来实现,队列一般使用链表实现,即链队列

链队列

原理

用链表表示的队列简称为链队列
一个链队列需要两个分别指示对头和队尾的阵阵才能唯一确定。

在这里插入图片描述

基本操作

队列的链式存储结构

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ERROR -1;
#define OK 1;
typedef char QElemType;

typedef struct QNode{
     //结点类型
	QElemType data;    //队列中结点的数据域
	struct QNode *next;//结点的指针域
}QNode,*QueuePtr; 

typedef struct{
           //链队列类型
	QueuePtr front;    //队头指针
	QueuePtr rear;     //队尾指针
}LinkQueue;

注意,我们队头指针指向链队列的头结点,队尾指针指向终端结点(虽然头结点不是必须,但为了方便操作,我们一般加上头结点)

初始化队列InitQueue

示意图:
在这里插入图片描述
代码

LinkQueue *InitQueue(){
   
	LinkQueue *Q = (LinkQueue *)malloc(sizeof(LinkQueue));
	Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
	
	Q->front->next = NULL;
	printf("初始化队列成功!\n");
	return Q;
}

入队列EnQueue

入队列是从队尾插入元素,就像排队,肯定是从队尾排队。
如何找到队尾呢?
这就要用到队尾指针了。
示意图:
在这里插入图片描述

在这里插入图片描述
代码

/**
 * 入队列
 * 1. 创建一个新结点分配内存
 * 2. 初始化新结点
 * 3. 插入新结点并移动队尾指针
 */
Status EnQueue(LinkQueue *Q, QElemType *e) {
   

	//创建一个新结点并分配内存
	QueuePtr T = (QueuePtr)malloc(sizeof(QNode));
	if(!T){
   
		printf("分配内存失败!");
		exit(OVERFLOW);
	}

	//初始化新结点
	T->data = e;
	T->next = NULL;

	//插入新结点并移动队尾指针
	Q->rear->next = T;
	Q->rear = T;

	return OK;
}

注意
⭐⭐⭐⭐⭐
代码里有一段代码

	Q->rear->next = T;//将新元素插入到队列末尾
	Q->rear = T;//队尾指针移动位置

我刚开始直接使用 Q->rear = p;错过了前面一步。前面的一步是必不可少的。
因为第一步代码是先将队列插入,第二步是移动队尾指针位置,两者并不重复。都很重要。

出队列DeQueue

思考思路:
1)判断是否为空队列
2)出队列即从队头删除元素,是不是似曾相识的感觉,没错,出栈和出队列的原理几乎相同。
示意图:
在这里插入图片描述
程序

/**
 * 出队列
 * 1. 判断队列是否为空 
 * 2. 删除队首元素
 * 3. 如果刚刚删除的是最后一个元素,将该队列置空
 * 4. 释放空间
 */
Status DeQueue(LinkQueue *Q, QElemType *e){
   

	QueuePtr p;

	//判断队列是否为空
	if(Q->front == Q->rear) {
   
		printf("队列为空!");
		exit(OVERFLOW);
	}
	
	//删除队首元素
	p = Q->front->next;
	*e = p->data;
	Q->front->next = p->next;

	//如果刚刚删除的是最后一个元素,将该队列置空
	if(Q->rear == p){
   
		Q->rear 
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值