数据结构(2)-队列

前言:

栈和队列很相似,上一篇插曲简单比较了线性表的顺序存储结构和链式存储结构,接下来继续回到正题,数据结构之队列。

1.what is queue(队列是啥啊?)

摘自《数据结构》:队列(queue)是一种先进先出(first in first out,缩写为FIFO)的线性表,它只允许在表的一端进行插入,而在另一端删除元素。如同排队,最先到的最先离开。

同样队列也有两种存储方式:链式存储和顺序存储

1.1先说链式队列:

队列的两种状态:

  • 当队列为空时,头指针(front)和尾指针(rear)指向同一基地址。如图a所示
  • 当队列不为空时,头指针和尾指针分别指向队列的开始和队列的最后一个元素,阴影部分是data,白色部分是地址,尾指针的地址是Null。如图b所示

那如何插入元素到队列中呢,和出队列呢?x入队列,则将原来的尾指针指向的结点的地址指向x的地址,再将尾指针(rear)指向x,尾结点的地址为null。同理再插入y。如下图a所示。

那么出队列呢,按照先进先出的原则,出队列从头部出,那就让头指针(front)指向下一个结点。此时就out啦!如下图b所示

ps:由于javascript的解释器针对数组都做了直接的优化,不会存在在很多编程语言中数组固定长度的问题(当数组填满后再添加就比较困难了,包括添加删除,都是需要把数组中所有的元素全部都变换位置的,javascript的的数组确实直接给优化好了,如push,pop,shift,unshift,split方法等等…)  所以JavaScript中常用的栈和队列都是基于数组的简单的顺序存储结构。如果要使用js来模拟链表结构 请看这篇博客

所以在此 就暂时不用链式结构来模拟链式队列了。

1.2 再说循环队列——队列的顺序表示和实现

在队列的顺序存储结构中,除了用一组地址连续的存储单元依次存放从队列到队尾的元素之外,还要加两个指针,分别指向队列的头元素和队列尾元素的位置。如下图a所示

我们分别来做几件事:

1. 第一件事如图b所示让五个元素入队列,此时front指向a,rear指向e。

2.第二件事 如图c所示 出队列一次,队列的头指针指向下个元素 此时front指向b

3.第三件事 如图d所示 再出队列3次,此时头指针指向e,尾指针也指向e.

4.假如 此时我再让元素f入队列,会发生什么。。。。。。。。。会发生错误,不能再让元素入队列了,因为存储单元给定是5个,再加入就越界了。

可是,明明下面还有4个空的存储单元可以被利用。此种使用方式 堪称实在是奢侈。那么怎样节约资源呢??

循环队列诞生啦!循环队列就是将顺序队列臆造为一个环状的空间。如图所示:

当头指针向下个元素移动时,留出的空间,可以继续入队列。解决了奢侈问题,但是否会引入其他问题呢?

先看它如何来做事:

1.如下图a所示,队列头元素时J3,尾元素是J5

2.如下图b所示,相继插入J6、J7、J8,此时队列空间被占满。此时Q.rear = Q.front;

PS:为什么队尾指针指向的是空元素?这是要看事先约定的。一般有两种方案:方案一、将队首指针指向实际队首,队尾指针指向队尾的下一个空位;方案二、将队首指针指向队首前一个空位,队尾指针指向实际队尾。这里用的是方案一。

那么问题来了...  当队列为空和队列为满的时候始终有Q.rear = Q.front; 如果仅凭 Q.rear = Q.front 是不能判断该队列是“空”还是“满”;

如何解决这个问题呢? 人为约束

1.可以约定另设一个标志位以区别队列是空还是满

2.少用一个元素的空间。

2.js模拟循环队列

循环队列是顺序结构,我们就用顺组来模拟。这里采用的是少用一个元素的空间来避免无法判断队列是空还是满的问题。

功能表

功能 功能描述
length 返回队列长度
inQueue 入队列
outQueue 出队列
clearQueue 清空队列
isEmpty 判断队列是否为空
function circleQueue(size){
    var cirQueue = [];
    this.size = size;
    this.maxsize = size + 1;
    this.front = 0;
    this.rear = 0;

    this.inQueue = function(element){
         if (typeof element == "undefined" || element = ""){
             return;
         }
         var pos = (this.rear +1) % this.maxsize;
         if(pos == this.front){
                 // 队列满
                 return;
         }else {
              this.cirQueue[this.rear] = element;
              this.rear = pos;
         }
    };
    this.outQueue = function(){
        if(this.rear == this.front){
            // 判断队列是否为空
            return;
        }else {
            var element = this.cirQueue[this.front];
            this.front = (this.front - 1)% this.maxsize;
            return element;
        }
    };

    this.length = function(){
         return (this.rear - this.front + this.maxsize) % this.maxsize;
    };

    this.clearQueue = function(){
        this.rear = 0;
    }

    this.isEmpty = function(){
        return this.rear == this.front;
    }
}
时间: 2024-10-26 03:13:36

数据结构(2)-队列的相关文章

简单数据结构之队列模拟

1 /************************************************************************************** 2 * Function : 模拟队列 3 * Create Date : 2014/04/23 4 * Author : NTSK13 5 * Email : [email protected] 6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性. 7 * 任何单位和个人不经本人允许不

数据结构 - 链队列的实行(C语言)

数据结构-链队列的实现 1 链队列的定义 队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已, 我们把它简称为链队列.为了操作上的方便,我们将队头指针指向链队列的头结点,而队尾指针指向终端结点,如下图所示. 空队列时,front和rear都指向头结点,如下图所示. 链队列的结构为: typedef int QElemType; /* QElemType类型根据实际情况而定,这里假设为int */ typedef struct QNode /* 结点结构 */ { QElemTy

数据结构 - 顺序队列的实行(C语言)

数据结构-顺序队列的实现 1 顺序队列的定义 线性表有顺序存储和链式存储,队列作为一种特殊的线性表,也同样存在这两种存储方式.我们先来看队列的顺序存储结构. 队列的顺序储存结构:用数组存储队列,为了避免当只有一个元素时,队头和队尾重合使得处理变得麻烦,所以引入两个指针:front指针指向队头元素,rear指针指向队尾元素的下一个位置,当front=rear时,为空队列,结构如下图所示. 假设是长度为5的数组,初始状态,空队列如下图左所示,front与 rear指针均指向下标为0的位置.然后入队a

数据结构之队列and栈总结分析

一.前言: 数据结构中队列和栈也是常见的两个数据结构,队列和栈在实际使用场景上也是相辅相成的,下面简单总结一下,如有不对之处,多多指点交流,谢谢. 二.队列简介 队列顾名思义就是排队的意思,根据我们的实际生活不难理解,排队就是有先后顺序,先到先得,其实在程序数据结构中的队列其效果也是一样,及先进先出.    队列大概有如下一些特性: 1.操作灵活,在初始化时不需要指定其长度,其长度自动增加(默认长度为32) 注:在实际使用中,如果事先能够预估其长度,那么在初始化时指定长度,可以提高效率    

数据结构专题——队列的应用 A1056.Mice and Rice ( 25)

#include <bits/stdc++.h> #include<math.h> #include <string> using namespace std; const int maxn = 1010; struct mouse{ int weight;//质量 int R;//排名 }mouse[maxn]; int main(){ int np,ng,order; scanf("%d%d",&np,&ng); for(int

数据结构之队列【转】

转自http://www.cnblogs.com/kaituorensheng/archive/2013/02/28/2937865.html 队列特性:先进先出(FIFO)——先进队列的元素先出队列.来源于我们生活中的队列(先排队的先办完事). 队列有下面几个操作: InitQueue() ——初始化队列 EnQueue()        ——进队列 DeQueue()        ——出队列 IsQueueEmpty()——判断队列是否为空 IsQueueFull()    ——判断队列是

数据结构之队列c代码实现

一学期的数据结构,总不能毫无收获吧,因为书上的很多代码并不能实现,我一个编程小白可怎么过呢,难得假期有时间,于是我寻求度娘,从四面八方找了些可以编译通过的源码,这一次是队列,后面我还会逐渐补充,如果有什么差错,欢迎大佬们来留言啊. 交一下代码: 1 #include<stdio.h> 2 #include<stdlib.h> 3 #define QUEEN_SIZE 50 4 5 typedef struct SeqQueue 6 { 7 int data[QUEEN_SIZE];

数据结构实践——队列数组

本文是针对数据结构基础系列网络课程(3):栈和队列的实践项目. [项目 - 队列数组] 创建10个队列,分别编号为0-9(处理为队列数组,编号即下标).输入若干个正整数,以数字0作为结束.设输入的值为x,其个位数字的大小为i,则将x插入到编号为i的队列中.最后输出所有的非空队列. 要求将队列处理成链式队列,使用链式队列算法库中定义的数据类型及算法,程序中只包括一个函数(main函数),入队和出队等操作直接在main函数中调用即可. 设程序运行时输入:70 59 90 72 67 88 80 64

数据结构:队列的顺序存储结构【转】

本文转载自:http://blog.csdn.net/jnu_simba/article/details/8841657 队列(Queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表.是一种先进先出的线性表(FIFO).允许插入的一端称为队尾,允许删除的一端称为队头.我们在<栈的顺序存储结构>中发现,栈操作的top指针在Push时增大而在Pop时减小,栈空间是可以重复利用的,而队列的front.rear指针都在一直增大,虽然前面的元素已经出队了,但它所占的存储空间却不能重复利用

大话数据结构----循环队列和链式队列

队列(Queue) 是只允许在一端进行插入操作,而在另一端进行删除操作的线性表 队列的特点就是:先进先出,和生活中排队的例子是很先进的,排队的目的不就是先到先得吗. 生活中的队列相当于顺序存储的队列,在火车站排队买票,前面的人买完票走了,后面的人一个一个往前移一位,这是很正常的事情,而计算机中队列队列第一个元素出去了,后面的元素一个一个往前移,这是一件很降低效率的一件事.为了解决这种效率问题,计算机采用循环队列的方式操作队数据. 循环队列 队列的头尾相接的顺序存储结构称为循环队列. 1.首先循环