java 队列实例_数据结构(Java)——队列的实例

本文介绍了Java API中的队列接口及其使用,通过编码解码消息的示例展示了队列如何存储重复密钥。此外,还模拟了售票口场景,讨论了不同数量售票口对顾客等待时间的影响,探讨了队列在链表和数组实现中的特点与差异。
摘要由CSDN通过智能技术生成

参考Java软件结构与数据结构 John Lewis Joseph chase 著 金名译

乱世英雄起四方,有枪就是草头王 ——易中天《百家讲坛》

1.JavaAPI中的队列

public interface Queueextends Collection

A collection designed for holding elements prior to processing. Besides basic Collection operations, queues provide additional insertion, extraction, and inspection operations. Each of these methods exists in two forms: one throws an exception if the operation fails, the other returns a special value (either null or false, depending on the operation). The latter form of the insert operation is designed specifically for use with capacity-restricted Queue implementations; in most implementations, insert operations cannot fail.

Operator

Throws exception

Returns special value

Insert

add(e)

offer(e)

Remove

remove()

poll()

Examine

element()

peek()

2.代码密钥

package ds.java.ch05;

import java.util.LinkedList;

import java.util.Queue;

/**

*@author LbZhang

*@version 创建时间:2015年11月17日 上午9:08:19

*@description 使用重复密钥来编码、解码消息 那些整数密钥值存储在一个队列中,使用一个密钥值之后,该值会被重新送回到队尾,

* 这样较长的消息可以按需继续重复使用该密钥。 注意:队列是一种可存储 重复编码密钥的便利 集合

*

* 解析:这个程序实际使用到了两份密钥,它们分别存储在两个单独的队列中。 思路:消息编码这使用一份密钥,消息解码者使用另一份密钥。

*

*/

public class Codes {

public static void main(String[] args) {

int[] key = { 5, 12, -3, 8, -9, 4, 10 };

Integer keyValue;

String encode = "";

String decode = "";

String message = "All programmers are playwrights and all "

+ "computers are lousy actors.";

Queue encodingQueue = new LinkedList();

Queue decodingQueue = new LinkedList();

/**

* 初始化密钥队列

*/

for(int i = 0;i

encodingQueue.add(key[i]);

decodingQueue.add(key[i]);

}

/**

*encode message

*/

for(int i=0;i

keyValue = encodingQueue.remove();

encode += (char) ((int)message.charAt(i) + keyValue.intValue());

encodingQueue.add(keyValue);

}

System.out.println("Encode Message :\n"+encode);

/**

*decode message

*/

for(int i=0;i

keyValue = decodingQueue.remove();

decode += (char) ((int)encode.charAt(i) - keyValue.intValue());

decodingQueue.add(keyValue);

}

System.out.println("Encode Message :\n"+decode);

/**

* 改程序在字母表结尾并没有环绕,他能够对unicode字符集中的任何字符编码,会将该字符移动到U字符集的另一个位置 包括标点符号

*/

}

}

3.售票口模拟

案例假设:

只排一对,而且先到的人先得到服务(这是一个队列)。

平均每隔15秒就会来一位顾客。

如果有空闲的售票口,在顾客抵达之时就会马上处理,在顾客抵达之时就会马上处理。

从顾客来到售票口到处理完顾客请求、到顾客离开,这个过程平均需要2分钟(120秒)。

3.1 Customer.java

package ds.java.ch05;

/**

*@author LbZhang

*@version 创建时间:2015年11月17日 上午10:11:02

*@description

* Customer对象负责跟踪顾客抵达售票口的时间和顾客买票后离开售票口的时间.

* 于是,顾客买票所花的总时间 就是抵达时间与离开时间之差。

* 辅助类

*/

public class Customer {

private int arrivalTime;

private int departureTime;

public Customer(int arrives) {

this.arrivalTime = arrives;

this.departureTime = 0;

}

public int getArrivalTime() {

return arrivalTime;

}

public void setArrivalTime(int arrivalTime) {

this.arrivalTime = arrivalTime;

}

public int getDepartureTime() {

return departureTime;

}

public void setDepartureTime(int departureTime) {

this.departureTime = departureTime;

}

public int totalTime(){

return departureTime-arrivalTime;

}

}

3.2 TicketCounter.java

package ds.java.ch05;

import java.util.LinkedList;

import java.util.Queue;

/**

*@author LbZhang

*@version 创建时间:2015年11月17日 上午10:27:12

*@description 模拟将创建一个顾客队列,接着观察如果仅有一个售票口,处理这些的购票需要多长时间,

* 然后在考虑两个售票口时,需要多少时间,接着再考虑三个售票口。继续这一过程直到达

* 到10个售票口最后我们比较每个顾客所需的平均处理时间。

* 由于假定每个15秒会来一个顾客(平均情况),于是可以预先载入一个顾客队列,在这个 模拟中将处理100位顾客

*/

public class TicketCounter {

final static int PROCESS = 120;// /处理时间

final static int MAX_CASHIERS = 10;//最大收银人数

final static int NUM_CUSTOMERS = 100;

public static void main(String[] args) {

Customer customer;

Queue customerQueue = new LinkedList();

int[] cashierTime = new int[MAX_CASHIERS];

//收银员的时间标记

int totalTime, averageTime, departs;

/** process the simulation for various number of cashiers */

for (int cashiers = 0; cashiers < MAX_CASHIERS; cashiers++) {

/** set each cashiers time to zero initially */

for (int count = 0; count < cashiers; count++)

cashierTime[count] = 0;

/** load customer queue */

for (int count = 1; count <= NUM_CUSTOMERS; count++)

customerQueue.offer(new Customer(count * 15));

totalTime = 0;//使用的总体时间

/** process all customers in the queue */

while (!(customerQueue.isEmpty())) {

//不同数量的收银员在进行售票的时候处理顾客服务的时间需求

for (int count = 0; count <= cashiers; count++) {

if (!(customerQueue.isEmpty())) {

customer = customerQueue.poll();

if (customer.getArrivalTime() > cashierTime[count])

departs = customer.getArrivalTime() + PROCESS;

else

departs = cashierTime[count] + PROCESS;

// 离开时间的设置

customer.setDepartureTime(departs);

cashierTime[count] = departs;

//每个顾客使用的最总时间

totalTime += customer.totalTime();

}

}

}

/** output results for this simulation */

averageTime = totalTime / NUM_CUSTOMERS;

System.out.println("Number of cashiers: " + (cashiers + 1));

System.out.println("Average time: " + averageTime + "\n");

}

}

}

4.队列的相关理解

-链表实现中head可能和tail引用相等:当队列为空或者队列中只有一个元素时会出现这种情况。

-环形数组实现中,front和rear可能相等:队列为空或者队列已满。

-dequeue操作复杂度为O(n)的非环形数组实现的时间复杂度最差。

-比较链式和数组实现:两种数组实现都会因为数组中为填充元素而浪费空间。链表中每个存储元素都会占用更多的存储空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值