特殊的线性表:队列

介绍完栈之后,接下来要介绍的是另一种跟栈很相似的数据结构 —— 队列,和栈一样,队列也是一中特殊的线性表结构,只不过队列是在一端插入,另一端删除,就跟我们平常排队一样的道理,从队尾入队,在队头出去,所以队列的特性是先入先出(FIFO),允许插入的一端叫队尾,允许删除的一端叫队头。一张图可以形象的体现两者的差别:

和栈一样,队列也可以通过数组和链表实现,通过数组实现的叫顺序队列,通过链表实现的叫做链式队列,栈只需要一个栈顶指针就可以了,因为只允许在栈顶插入删除,但是队列需要两个指针,一个指向队头,一个指向队尾。我们先来看通过 PHP 数组实现的顺序队列代码:

<?php
/**
 * 通过 PHP 数组实现的队列
 */
class SimpleQueue
{
    private $_queue = [];
    private $_size = 0;

    public function __construct($size = 10)
    {
        $this->_size = $size;
    }

    // 入队
    public function enqueue($value)
    {
        if (count($this->_queue) > $this->_size) {
            return false;
        }
        array_push($this->_queue, $value);
    }

    // 出队
    public function dequeue()
    {
        if (count($this->_queue) == 0) {
            return false;
        }
        return array_shift($this->_queue);
    }

    public function size()
    {
        return count($this->_queue);
    }
}

$queue = new SimpleQueue(5);
$queue->enqueue(1);
$queue->enqueue(3);
$queue->enqueue(5);
var_dump($queue->dequeue());  # 1
var_dump($queue->size());  # 2

通过数组实现的顺序队列有一个问题,就是随着队列元素的插入和删除,队尾指针和队头指针不断后移,而导致队尾指针指向末尾无法插入数据,这时候有可能队列头部还是有剩余空间的,如下图所示:

我们当然可以通过数据搬移的方式把所有队列数据往前移,但这会增加额外的时间复杂度,如果频繁操作数据量很大的队列,显然对性能有严重损耗,对此问题的解决方案是循环队列,即把队列头尾连起来:

这样一来就不会出现之前的问题了,此时判断队列是否为空的条件还是tail==head,但是判断队列是否满的条件就变成了 (tail+1) % maxsize == head,maxsize 是数组的长度,浪费一个空间是为了避免混淆判断空队列的条件。当然如果通过链表来实现队列的话,显然没有这类问题,因为链表没有空间限制。

队列的应用也非常广泛,比如我们常见的消息队列就是队列的典型应用场景。

原文地址:https://www.cnblogs.com/mzhaox/p/11294252.html

时间: 2024-08-30 03:41:32

特殊的线性表:队列的相关文章

数据结构和算法学习总结03 线性表---队列

队列 队列(Queue)是限定只能在表的一端进行插入和在另一端进行删除操作的线性表. 与栈的比较: 1.队列先进先出,栈先进后出. 2.从"数据结构"的角度看,它们都是线性结构,即数据元素之间的关系相同. 但它们是完全不同的数据类型.除了它们各自的基本操作集不同外,主要区别是对插入和删除操作的"限定": 栈是限定只能在表的一端进行插入和删除操作的线性表:队列是限定只能在表的一端进行插入和在另一端进行删除操作的线性表. 队列同样分为顺序队列和链式队列,我们一般用链式队

Java学习笔记(2)----散列集/线性表/队列/集合/图(Set,List,Queue,Collection,Map)

1. Java集合框架中的所有实例类都实现了Cloneable和Seriablizable接口.所以,它们的实例都是可复制和可序列化的. 2. 规则集存储的是不重复的元素.若要在集合中存储重复的元素,就需要使用线性表.线性表不仅可以存储重复的元素,而且允许用户指定存储的位置.用户可以通过下标来访问线性表中的元素. 3. Java集合支持三种类型的规则集:散列集HashSet.链式散列集LinkedHashSet和树形集TreeSet.HashSet以一个不可预知的顺序存储元素:LinkedHas

线性表-队列

简介 队列是一种特殊的线性表.从队头删除,从队尾插入. 拓扑排序 对一个有向无环图G进行拓扑排序,是指将G中所有顶点排成线性序列,使得图中任意一对顶点u,v,若边(u,v)属于E(G),则u在线性序列中出现在v之前.

2.线性表——队列

1.什么是队列 [1] 队列只允许在表的前端(front)进行删除操作,且在表的后端(rear)进行添加操作: [2] 队列是“先进先出”,进行插入操作的后端称为队尾rear,进行删除操作的前端称为队首front: [3] 队列的种类:顺序队列和循环队列. [4] 队列同栈一样,即能利用数组实现(线性存储),也能利用链表实现(链式存储). [5] 队列的表示: 1.1 队列的表示 2.栈的基本操作 [1] 队列的存储结构 [2] 进队 [3] 出队 [4] 判断空,判断满 [5] 队列的遍历 [

(源代码见大话数据结构)线性表—队列的链式存储结构-&gt;出队&amp;入队&amp;建立空队列

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 20 #define OVERFLOW 0 typedef int Status; typedef int QElemType; typedef struct QNode//标识符和类型名一样不知道什么用意.. { QElemType data; stru

数据结构-线性表-队列

队列的特别实现 组合使用两个栈的后进先出可以实现队列的先进先出,简单高效,入队和出队的时间复杂度可以到 O(1) SQueue.h #ifndef _SQUEUE_H_ #define _SQUEUE_H_ typedef void SQueue; SQueue* SQueue_Create(); void SQueue_Destroy(SQueue* queue); void SQueue_Clear(SQueue* queue); int SQueue_Append(SQueue* queu

多态实现线性表(队列,串,堆栈)

试用多态实现线性表(队列,串,堆栈),要求具备线性表的基本操作,插入,删除,测长等. #include<iostream> using namespace std; template<typename t> struct tcontainer { virtual void push(const t&) = 0; virtual void pop() = 0; virtual const t& begin() = 0; virtual const t& end

线性表之栈与队列

一.栈是限定仅在表尾进行插入和删除操作的线性表 队列是只允许在一端进行插入操作,而在另另一端进行删除操作的线性表. 允许插入和删除的一端称为栈顶,另一端称为栈底,不包含任何数据元素的栈称为空栈,栈称为后进先出  LIFO结构 栈的抽象数据类型 ADT 栈 (stack) Data 同线性表.元素具有相同的类型,相邻元素具有前驱和后继关系 Operation InitStack(*S):初始化操作,建立一个空栈S DestroyStack(*S):若栈存在,则销毁它 ClearStack(*S):

[考研系列之数据结构]线性表之队列

基本概念 队列的定义 队列是一种只能在表的一头插入,另一头删除的线性表,简而言之具有FIFO的特性 组成 队头 队尾 扩展 双端队列 只能在两端进行删除插入操作的线性表 实现 链队列 顺序队列 循环队列 循环队列 循环队列是将顺序队列臆造成一个环,如图 循环队列有以下参数 front 指向队头的指针 rear 指向队尾的指针 SIZE 循环最大队列长度 对于循环队列,初始状态的时候 front=rear=0; 每次insert的时候 Insert((front++)%SIZE); 那么,当循环队

数据结构回顾之顺序存储结构中的线性表(栈与队列顺序线性表实现)

说到数据结构呢,对于一个Coder来说还是蛮重要的啦,每次看数据结构的东西都有新的收获,这两天在回顾数据结构的知识.当然啦,虽然数据结构有些是理论的东西,如果好好的理解数据结构的东西还是少不了的代码的支撑的.数据结构简单的来说吧,可以分为两大类,一个是数据的"物理存储结构",另一种是数据的"逻辑存储结构".数据的"物理存储结构"又可分为顺序的和链式的(下面将会结合着代码打印内存地址的形式来观察物理存储结构). 逻辑存储结构又可分为集合,线性, 树