写在前面的话:

一枚自学Java和算法的工科妹子。

  • 算法学习书目:算法(第四版) Robert Sedgewick
  • 算法视频教程:Coursera  Algorithms Part1&2

本文是根据《算法(第四版)》的个人总结,如有错误,请批评指正。

一、队列的定义

先进先出队列(简称队列)是一种基于先进先出(FIFO)策略的集合类型。

当foreach语句迭代访问队列中的元素时,元素的处理顺序就是它们添加到队列中的顺序。

二、队列的实现

1.数组实现(可动态调整数组大小的队列)

import java.util.Iterator;
import java.util.NoSuchElementException; public class ResizingArrayQueue<Item> implements Iterable<Item> {
private Item[] q; // queue elements
private int n; // number of elements on queue
private int first; // index of first element of queue
private int last; // index of next available slot public ResizingArrayQueue() {
q = (Item[]) new Object[2];
n = 0;
first = 0;
last = 0;
} public boolean isEmpty() {
return n == 0;
} public int size() {
return n;
} private void resize(int capacity) {
assert capacity >= n;
Item[] temp = (Item[]) new Object[capacity];
for (int i = 0; i < n; i++) {
temp[i] = q[(first + i) % q.length];
}
q = temp;
first = 0;
last = n;
} public void enqueue(Item item) {
// double size of array if necessary and recopy to front of array
if (n == q.length) resize(2*q.length); // double size of array if necessary
q[last++] = item; // add item
if (last == q.length) last = 0; // wrap-around
n++;
} public Item dequeue() {
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
Item item = q[first];
q[first] = null; // to avoid loitering
n--;
first++;
if (first == q.length) first = 0; // wrap-around
// shrink size of array if necessary
if (n > 0 && n == q.length/4) resize(q.length/2);
return item;
} public Item peek() {
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
return q[first];
} public Iterator<Item> iterator() {
return new ArrayIterator();
} private class ArrayIterator implements Iterator<Item> {
private int i = 0;
public boolean hasNext() { return i < n; }
public void remove() { throw new UnsupportedOperationException(); } public Item next() {
if (!hasNext()) throw new NoSuchElementException();
Item item = q[(i + first) % q.length];
i++;
return item;
}
} public static void main(String[] args) {
ResizingArrayQueue<String> queue = new ResizingArrayQueue<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) queue.enqueue(item);
else if (!queue.isEmpty()) StdOut.print(queue.dequeue() + " ");
}
StdOut.println("(" + queue.size() + " left on queue)");
} }

2.链表实现

import java.util.Iterator;
import java.util.NoSuchElementException; public class Queue<Item> implements Iterable<Item> {
private Node<Item> first; // beginning of queue
private Node<Item> last; // end of queue
private int n; // number of elements on queue // helper linked list class
private static class Node<Item> {
private Item item;
private Node<Item> next;
} public Queue() {
first = null;
last = null;
n = 0;
} public boolean isEmpty() {
return first == null;
} public int size() {
return n;
} public Item peek() {
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
return first.item;
} // 在表尾插入结点
public void enqueue(Item item) {
Node<Item> oldlast = last;
last = new Node<Item>();
last.item = item;
last.next = null;
if (isEmpty()) first = last;
else oldlast.next = last;
n++;
} // 在表头删除结点
public Item dequeue() {
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
Item item = first.item;
first = first.next;
n--;
if (isEmpty()) last = null; // to avoid loitering
return item;
} public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this) {
s.append(item);
s.append(' ');
}
return s.toString();
} public Iterator<Item> iterator() {
return new ListIterator<Item>(first);
} private class ListIterator<Item> implements Iterator<Item> {
private Node<Item> current; public ListIterator(Node<Item> first) {
current = first;
} public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException(); } public Item next() {
if (!hasNext()) throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
} public static void main(String[] args) {
Queue<String> queue = new Queue<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-"))
queue.enqueue(item);
else if (!queue.isEmpty())
StdOut.print(queue.dequeue() + " ");
}
StdOut.println("(" + queue.size() + " left on queue)");
}
}

两种实现方式的比较见前一篇文章----下压栈(LIFO)详解

三、队列的应用

In类的静态方法readInts()的一种实现

注意:《算法(第四版)》书中为了方便向文件中读取和写入原始数据类型(或String类型),提供了In和Out API。感兴趣的朋友可以去http://algs4.cs.princeton.edu/下载。

代码的解释:In类中的readInt()方法,其实就是用了Scanner中的nextInt()方法,读取一个整数;

Queue类是用链表实现的队列。

readInts()作用:这个方法为用例解决的问题是用例无需预先知道文件的大侠即可将文件中的所有整数读入一个数组中。

  • 将文件中所有的整数读入队列(链表实现的),用enqueue()方法;
  • Queue类的size()方法得到队列中元素的数目,即确定数组的大小;
  • 创建数组,并将队列的所有整数移动到数组中,用dequeue()方法。

队列之所以合适是因为它的先进先出策略,可以将所有的整数按照文件中的顺序放入数组中。

public static int[] readInts(String name){

    In in = new In(name);
Queue<String> q = new Queue<String>; while(!in.isEmpty()){
q.enqueue(in.readInt());
} int N = q.size();
int[] a = new int[N];
for(int i = 0; i < N; i++)
a[i]=q.dequeue(); return a;
}

作者: 邹珍珍(Pearl_zhen)

出处: http://www.cnblogs.com/zouzz/

声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文链接 如有问题, 可邮件(zouzhenzhen@seu.edu.cn)咨询.

队列(FIFO)详解的更多相关文章

  1. WCF中队列服务详解

    WCF中队列服务详解 一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务 ...

  2. BlockingQueue(阻塞队列)详解

    一. 前言 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量 ...

  3. JUC组件扩展(三):BlockingQueue(阻塞队列)详解

    一. 前言 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大 ...

  4. 转 BlockingQueue(阻塞队列)详解

    转自 http://wsmajunfeng.iteye.com/blog/1629354 前言: 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输” ...

  5. 【FreeRTOS学习04】小白都能懂的 Queue Management 消息队列使用详解

    消息队列作为任务间同步扮演着必不可少的角色: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 相关文章 1 前言 2 xQUEUE 3 相关概念 3 ...

  6. Java并发编程3-抽象同步队列AQS详解

    AQS是AtractQueuedSynchronizer(队列同步器)的简写,是用来构建锁或其他同步组件的基础框架.主要通过一个int类型的state来表示同步状态,内部有一个FIFO的同步队列来实现 ...

  7. DPDK 无锁环形队列(Ring)详解

    DPDK 无锁环形队列(Ring) 此篇文章主要用来学习和记录DPDK中无锁环形队列相关内容,结合了官方文档说明和源码中的实现,供大家交流和学习. Author : Toney Email : vip ...

  8. 跟我一起学WCF(11)——WCF中队列服务详解

    一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务队列的方法来支持客户端 ...

  9. jQuery队列控制方法详解queue()/dequeue()/clearQueue()

    queue(name,[callback]):  当只传入一个参数时, 它返回并指向第一个匹配元素的队列(将是一个函数数组,队列名默认是fx);$('#demo').queue('name') 当有两 ...

  10. C++ STL 双端队列deque详解

    一.解释 Deque(双端队列)是一种具有队列和栈的性质的数据结构.双端队列的元素可以从两端弹出,其限定插入和删除操作在表的两端进行. 二.常用操作: 1.头文件 #include <deque ...

随机推荐

  1. javascript一个作用域案例分析

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. javascript中in用法介绍

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. jQuery中事件模块介绍

    事件模块 1.提供其他DOM方法 包括:next 和 nextAll方法 1.1 next方法实现 目标:扩展框架方法,获取当前元素的下一个元素 问题:如何获取下一个元素? 1.1.1 提供 next ...

  4. SQL Server数据库备份的几个建议

    1.定期进行数据备份(完备或差异备份)和日志备份. 2.使用压缩备份来减少磁盘空间占用和提高备份效率. 3.定期检查磁盘剩余空间和备份文件增长情况,以确保有足够空间进行下一次备份. 4.使用校验和(C ...

  5. (转)shiro权限框架详解02-权限理论介绍

    http://blog.csdn.net/facekbook/article/details/54893042 权限管理解决方案 本文主要介绍权限管理的解决方法: 粗颗粒度和细颗粒度 基于url拦截 ...

  6. RabbitMQ学习笔记(4)----RabbitMQ Exchange(交换机)的使用

    1. fanout模式 1.1 Publish/Subscribe(发布/订阅)结构图 上图表示一个消费者消费消息之后,不讲消息直接存储到队列,而是使用两个消费者各自声明一个队列,将各自的对应的队列与 ...

  7. Spring Boot 项目学习 (一) 项目搭建

    0 引言 本文主要记录借用Idea 开发环境下,搭建 Spring Boot 项目框架的过程. 1 系列文档目录 Spring Boot 项目学习 (一) 项目搭建 Spring Boot 项目学习 ...

  8. 初步使用vue中axios

    1.下载axios npm install axios --save 2.两种方式使用axios (1)在模块中引入axios 例如:我在用户登陆界面需要使用axios,就在login页面引入,不是全 ...

  9. .net 技术基础

    C#常见运算符 一元运算符(+.-.!.~.++.--) 算术运算符(*./.%.+ . – ) 移位运算符(<< .>> ) 关系和类型测试运算符(==.!=.<.&g ...

  10. Linux 中常用的基础命令二

    1.Linux文件分层结构  FHS:Linux有一个组织叫LSB定义的Linux发行版基础目录名称命名法则及功用规定,这种标准叫FHS文件系统层级标准./bin   存放可执行的二进制程序,管理员和 ...