队列(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 ...
随机推荐
- Unity3d transform
using UnityEngine; using System.Collections; public class transform : MonoBehaviour { // Use this fo ...
- Array.of()和Array()区别
Array.of方法用于将一组值,转换为数组. Array.of(3, 11, 8) // [3,11,8] Array.of(3) // [3] Array.of(3).length // 1 这个 ...
- Android学习——利用RecyclerView编写聊天界面
1.待会儿会用到RecyclerView,首先在app/build.gradle(注意有两个build.gradle,选择app下的那个)当中添加依赖库,如下: dependencies { comp ...
- draw9patch在SDK->tools找不到,在Android Studio点击图片没找到draw9patch
draw9patch在SDK->tools找不到,在Android Studio点击图片没找到draw9patch 第一个问题: Google把draw9patch集成在Android Stud ...
- 【SQL】分析函数功能-排序
1:排名,不考虑并列问题 row_number() 2:排名,有并列,并列后的排名不连续 rank() 3:排名,有并列,并列后的排名连续 dense_rank() 测试: SQL> creat ...
- ERROR 1062 (23000): Duplicate entry for key 'PRIMARY'
ALTER TABLE table1 ADD COLUMN column1 VARCHAR(400) DEFAULT NULL; ERROR 1062 (23000): Duplicate entry ...
- 励志:98岁老爷爷用Windows系统自带画图软件制作的神作
哈尔拉斯科,是一位很出名的老爷爷,他70岁才接触MS Paint(就是我们熟知的Windows自带的画图软件).他曾经是一名图形艺术家,但是之前他都是手工创作.他熟知怎么用双手进行艺术创作.但是后来, ...
- Python基础:条件判断 &&循环
1:条件判断 2:循环 2.1:for 2.2 while 小结: continue :跳出本次循环 进行下次循环, break :结束循环体.
- MySQL_pymysql模块
安装:pip install pymysql 基本操作 import pymysql conn=pymysql.connect(host=',database='lary',charset='utf8 ...
- vc++元文件的保存,保存图形,重绘图形
1, CMateFileDC 可以用来多次打开自己的画布,这个元文件包含许多接口的命令 当绘制好之后可以用来播放元文件 首先,创建一个CMateFileDC的元文件对象 然后调用Create原函数,创 ...