数据结构 队列

目录

一.队列基础知识

二.循环队列

1.基础知识

1.1问题提出

1.2循环队列的体现

2.代码实现

2.1头文件的设计

2.2初始化

2.3入队

2.4出队

2.5判空,判满 

2.6获取有效值个数

2.7 搜索,获取队头元素值,清空,销毁,打印

3.测试

三.链队列

1.基础知识

2.代码实现

2.1头文件的设计

2.2初始化

2.3入队

2.4出队

2.5获取对头元素值,搜索,判空,判满,获取有效值个数,清空,销毁,打印

3.测试


一.队列基础知识

抽象数据类型队列的定义:

和栈相反,队列(queue)是一种先进先出(first in first out,缩写为FIFO)的线性表。它只允许在表的一段进行插入,而在另一端进行删除元素。这和我们日常生活中的排队类似,最早排队的最早离开。在队列中,允许插入的一端叫作队尾(rear),允许删除的一端叫作对头(front)。假设队列为q=(a1,a2,...an),那么a1就是队头元素,an就是队尾元素。队列中的元素是按照a1,a2,...an进入的,退出队列也只能按照这个次序退出。

 

        在电脑允许过程中,有时会出现疑似死机状态,双击任何快捷方式都不动弹。 过一会儿它又会突然恢复允许,将你刚刚所点击的操作全部执行一遍。这是因为操作系统在当时可能CPU一时忙不过来,等前面的事完成的事忙完后,后面多个指令需要通过一个通道输出,按先后次序排队执行造成的结果。这也是一个最典型的例子就是操作系统中的作业排队,在允许多道程序的计算机系统中,同时有几个作业运行。如果运行的结果都需要通过通道输出,那就要按请求输出的先后次序排队。

   线性表有顺序存储和链式存储,栈是线性表,具有这两种存储方式。同样,队列作为一种特殊的线性表,也同样存在这两种存储方式。

二.循环队列

1.基础知识

1.1问题提出

1.1.1假设用顺序表去实现队列,出队和入队的时间复杂度为多少?

我们先回忆一下用顺序表和链表实现栈时,出栈和入栈的时间复杂度。因为出栈和入栈均不需要挪动元素,所以不管是顺序栈还是链栈,出栈和入栈的时间复杂度均为O(1)。

现在则假设用顺序表实现队列:

队列需要一端插入一端删除。而我们用顺序表实现队列,则有两种可能性:(1)头部插入O(n)尾部删除O(1)(2)头部删除O(1)尾部插入O(n)。由此看来如果用简单的顺序表来实现顺序队列,没有办法让入队和出队的时间复杂度都达到O(1)。

1.1.2对上一个问题如何进行改善?*难点一

举例理解:如果你在坐高铁的途中想买零食,你应该怎么办?是选择自己去买,还是等待乘务人员推着小推车过来,到你身边时你再买?答案显而易见是后者。

我们发现在买零食的过程中乘客不动,乘务员移动。我们把这种思想放在队列中理解一下。也就是说在队列操作过程中让数据不动,而是让对头指针和队尾指针去挪动。也就是说。队头不需要一定在下标为0的位置。

1.2循环队列的体现

 为了避免当只有一个元素时,队头和队尾重合使处理变得麻烦,所以引入两个指针,front指针指向队头元素,rear指针指向队尾元素的下一个位置,这样当front等于rear时,此队列不是还剩一个元素,而是空队列。

 

假设当前为队列分配的最大空间为6,再进行了一些列的入队出队操作之后,当队列处于尾部指针指向6号下标时,不可再继续插入新的队尾元素,否则会因数组越界而遭致程序代码被破坏。然而此时又不能像顺序栈一样再分配扩大数组空间,因为队列的实际可用空间并未占满。这时可以选择将顺序队列臆造成一个环状的空间,称之为循环队列

 

2.代码实现

2.1头文件的设计

#pragma once

//循环队列的结构体设计:
typedef int ELEM_TYPE;
#define MAX_SIZE 100

typedef struct Queue
{
	ELEM_TYPE *base;//用来接收malloc在堆内申请的连续内存,用于分配空间
	int front;//队头指针,若队列不空,则指向队头元素
	int rear;//队尾指针,若队列不空,则指向队列尾元素的下一个位置

	//int length;//用于第二个难点:用于区分判空判满条件
}Queue, *PQueue;


//可实现的操作:

//初始化
void Init_queue(struct Queue* qu);

//入队
bool Push(struct Queue *qu, ELEM_TYPE val);

//出队
bool Pop(struct Queue *qu);

//获取队头元素值
ELEM_TYPE Front(struct Queue *qu);

//搜索
int Search(struct Queue *qu, ELEM_TYPE val);

//判空
bool Is_Empty(struct Queue *qu);

//判满
bool Is_Full(struct Queue *qu);

//获取有效值个数
int Get_length(struct Queue *qu);

//清空
void Clear(PQueue qu);

//销毁
void Destroy(PQueue qu);

//打印
void Show(PQueue qu);

2.2初始化

//初始化
void Init_queue(struct Queue* qu)
{
	//assert

	qu->base = (ELEM_TYP
  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值