队列(FIFO)详解
写在前面的话:
一枚自学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)详解的更多相关文章
- WCF中队列服务详解
WCF中队列服务详解 一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务 ...
- BlockingQueue(阻塞队列)详解
一. 前言 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量 ...
- JUC组件扩展(三):BlockingQueue(阻塞队列)详解
一. 前言 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大 ...
- 转 BlockingQueue(阻塞队列)详解
转自 http://wsmajunfeng.iteye.com/blog/1629354 前言: 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输” ...
- 【FreeRTOS学习04】小白都能懂的 Queue Management 消息队列使用详解
消息队列作为任务间同步扮演着必不可少的角色: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 相关文章 1 前言 2 xQUEUE 3 相关概念 3 ...
- Java并发编程3-抽象同步队列AQS详解
AQS是AtractQueuedSynchronizer(队列同步器)的简写,是用来构建锁或其他同步组件的基础框架.主要通过一个int类型的state来表示同步状态,内部有一个FIFO的同步队列来实现 ...
- DPDK 无锁环形队列(Ring)详解
DPDK 无锁环形队列(Ring) 此篇文章主要用来学习和记录DPDK中无锁环形队列相关内容,结合了官方文档说明和源码中的实现,供大家交流和学习. Author : Toney Email : vip ...
- 跟我一起学WCF(11)——WCF中队列服务详解
一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务队列的方法来支持客户端 ...
- jQuery队列控制方法详解queue()/dequeue()/clearQueue()
queue(name,[callback]): 当只传入一个参数时, 它返回并指向第一个匹配元素的队列(将是一个函数数组,队列名默认是fx);$('#demo').queue('name') 当有两 ...
- C++ STL 双端队列deque详解
一.解释 Deque(双端队列)是一种具有队列和栈的性质的数据结构.双端队列的元素可以从两端弹出,其限定插入和删除操作在表的两端进行. 二.常用操作: 1.头文件 #include <deque ...
随机推荐
- P1982 小朋友的数字
题目描述 有 n 个小朋友排成一列.每个小朋友手上都有一个数字,这个数字可正可负.规定每个 小朋友的特征值等于排在他前面(包括他本人)的小朋友中连续若干个(最少有一个)小朋 友手上的数字之和的最大值. ...
- mysql5.5和5.6版本更新内容
mysql 5.5,5.6 比5.1改进地方: 1,5.5默认存储引擎为innodb2,5.5增加cpu多核处理能力:innodb_read_io_threads innodb_write_io_th ...
- C#中null、""、string.empty区别
(1)NULLnull 关键字是表示不引用任何对象的空引用的文字值.null 是引用类型变量的默认值.那么也只有引用型的变量可以为NULL,如果int i=null,的话,是不可以的,因为Int是值类 ...
- (转)基于MVC4+EasyUI的Web开发框架经验总结(5)--使用HTML编辑控件CKEditor和CKFinder
http://www.cnblogs.com/wuhuacong/p/3780356.html Web开发上有很多HTML的编辑控件,如CKEditor.kindeditor等等,很多都做的很好,本文 ...
- MongoDB 学习笔记(三):分页、排序与游标
一.分页 1.limit返回指定条数的数据 2.skip指定跨度 3.limit与skip结合,进行分页 二.排序 1.sort排序:指定排序的key,大于0为升序,小于0为降序.如果指定了多个排序键 ...
- 洛谷P3113 [USACO14DEC]马拉松赛跑Marathon_Gold 线段树维护区间最大值 模板
如此之裸- Code: #include<cstdio> #include<cstring> #include<cmath> #include<algorit ...
- 了解http协议
http:超文本传输协议 https:安全超文本传输协议 FTP:文件传输协议 TCP:网络控制协议 IP:互联网协议 UDP:用户数据协议 https协议特点-------------------- ...
- Linux内核crash/Oops异常定位分析方法
在内核开发的过程中,经常会碰到内核崩溃,比如空指针异常,内存访问越界.通常我们只能靠崩溃之后打印出的异常调用栈信息来定位crash的位置和原因.总结下分析的方法和步骤. 通常oops发生之后,会在串口 ...
- python中的网页标签等字符处理
# -*- coding: utf-8-*- import re ##过滤HTML中的标签 #将HTML中标签等信息去掉 #@param htmlstr HTML字符串. def filter_tag ...
- Virtual servers on a Raspberry Pi with the light weight OS virtualization system Docker!
转自:http://www.hyggeit.dk/2014/02/virtual-servers-on-raspberry-pi-with.html Virtual servers on a Rasp ...