1.使用队列:方块舞的舞伴分配问题                                    

前面我们提到过,经常用队列模拟排队的人。下面我们使用队列来模拟跳方块舞的人。当
男男女女来到舞池,他们按照自己的性别排成两队。当舞池中有地方空出来时,选两个队
列中的第一个人组成舞伴。他们身后的人各自向前移动一位,变成新的队首。当一对舞伴
迈入舞池时,主持人会大声喊出他们的名字。当一对舞伴走出舞池,且两排队伍中有任意
一队没人时,主持人也会把这个情况告诉大家。
为了模拟这种情况,我们把跳方块舞的男男女女的姓名储存在一个文本文件中:
 
下面是程序代码的实现:
<script type="text/javascript">
function Queue(){
this.dataStore = [];
this.enqueue = enqueue;
this.dequeue = dequeue;
this.front = front;
this.back = back;
this.toString = toString;
this.empty = empty;
this.count = count;
} /**
* 向队尾添加一个元素
*/
function enqueue(element){
this.dataStore.push(element);
} /**
* 删除队首的元素:
*/
function dequeue(){
this.dataStore.shift();
} /**
* 读取队首的元素:
*/
function front(){
return this.dataStore[0];
} /**
* 读取队尾的元素:
*/
function back(){
return this.dataStore[this.dataStore.length - 1];
} /**
* 显示队列内的所有元素
*/
function toString(){
var retStr = "";
for (var i = 0; i < this.dataStore.length; ++i) {
retStr += this.dataStore[i] + "\n";
}
return retStr;
} /**
* 判断队列是否为空
*/
function empty(){
if(this.dataStore.length == 0){
return true;
}else{
return false;
}
} /**
* 显示队列中有多少个元素
*/
function count(){
return this.dataStore.length;
} //===================================使用Queue类=============================================
/**
* 每个舞者信息都被存储在一个Dancer 对象中
*/
function Dancer(name, sex) {
this.name = name;
this.sex = sex;
} /**
* 将舞者信息从文件中读到程序里来
* trim() 函数除去了每行字符串后的空格
* 根据性别,将舞者加入不同的队列
*/
function getDancers(males, females){
var names = read("dancers.txt").split("\n");
for (var i = 0; i < names.length; ++i) {
names[i] = names[i].trim();
}
for (var i = 0; i < names.length; ++i) {
var dancer = names[i].split(" ");
var sex = dancer[0];
var name = dancer[1];
if (sex == "F") {
females.enqueue(new Dancer(name, sex));
}else{
males.enqueue(new Dancer(name, sex));
}
}
} /**
* 将男性和女性组成舞伴,并且宣布配对结果
*/
function dance(males, females){
console.log("The dance partners are: \n");
while (!females.empty() && !males.empty()) {
person = females.dequeue();
console.log("Female dancer is: " + person.name);
person = males.dequeue();
console.log(" and the male dancer is: " + person.name);
}
} /**
*测试程序:
*/
var maleDancers = new Queue();
var femaleDancers = new Queue();
getDancers(maleDancers, femaleDancers);
dance(maleDancers, femaleDancers);
if (!femaleDancers.empty()) {
print(femaleDancers.front().name + " is waiting to dance.");
}
if (!maleDancers.empty()) {
print(maleDancers.front().name + " is waiting to dance.");
} //显示等候跳舞的人数
if (maleDancers.count() > 0) {
print("There are " + maleDancers.count() +" male dancers waiting to dance.");
}
if (femaleDancers.count() > 0) {
print("There are " + femaleDancers.count() +" female dancers waiting to dance.");
} </script>

2.使用队列对数据进行排序                                        

队列不仅用于执行现实生活中与排队有关的操作,还可以用于对数据进行排序。
计算机刚刚出现时,程序是通过穿孔卡输入主机的,每张卡包含一条程序语句。
这些穿孔卡装在一个盒子里,经一个机械装置进行排序。我们可以使用一组队列来模拟这一过程。
这种排序技术叫做基数排序,它不是最快的排序算法,但是它展示了一些有趣的队列使用方法。
 
对于0~99 的数字,基数排序将数据集扫描两次。
第一次按个位上的数字进行排序,第二次按十位上的数字进行排序。每个数字根据对应位上的数值被分在不同的盒子里。
假设有如下数字:
91, 46, 85, 15, 92, 35, 31, 22
 
经过基数排序第一次扫描之后,数字被分配到如下盒子中:

根据盒子的顺序,对数字进行第一次排序的结果如下:

91, 31, 92, 22, 85, 15, 35, 46
 
然后根据十位上的数值再将上次排序的结果分配到不同的盒子中:
最后,将盒子中的数字取出,组成一个新的列表,该列表即为排好序的数字:

15, 22, 31, 35, 46, 85, 91, 92
 
使用队列代表盒子,可以实现这个算法。

我们需要十个队列,每个对应一个数字。将所有队列保存在一个数组中,使用取余和除法操作决定个位和十位。
算法的剩余部分将数字加入相应的队列,根据个位数值对其重新排序,然后再根据十位上的数值进行排序,
结果即为排好序的数字。
 
下面是代码的实现:
<script type="text/javascript">
function Queue(){
this.dataStore = [];
this.enqueue = enqueue;
this.dequeue = dequeue;
this.front = front;
this.back = back;
this.toString = toString;
this.empty = empty;
this.count = count;
} /**
* 向队尾添加一个元素
*/
function enqueue(element){
this.dataStore.push(element);
} /**
* 删除队首的元素:
*/
function dequeue(){
return this.dataStore.shift();
} /**
* 读取队首的元素:
*/
function front(){
return this.dataStore[0];
} /**
* 读取队尾的元素:
*/
function back(){
return this.dataStore[this.dataStore.length - 1];
} /**
* 显示队列内的所有元素
*/
function toString(){
var retStr = "";
for (var i = 0; i < this.dataStore.length; ++i) {
retStr += this.dataStore[i] + "\n";
}
return retStr;
} /**
* 判断队列是否为空
*/
function empty(){
if(this.dataStore.length == 0){
return true;
}else{
return false;
}
} /**
* 显示队列中有多少个元素
*/
function count(){
return this.dataStore.length;
} //===================================使用Queue类=============================================
/**
* 根据相应位(个位或十位)上的数值,将数字分配到相应队列
* nums: 待排序的数组
* queues: 队列数组
* n: nums的length
* 参数digit 1-按照个位数排序,10-按照十位数排序
*/
function distribute(nums, queues, n, digit){
for(var i=0; i<n; i++){
if(digit == 1){
queues[nums[i]%10].enqueue(nums[i]);
}else{
var k = Math.floor(nums[i]/10);
queues[k].enqueue(nums[i]);
}
}
} /**
* 从队列中收集数字的函数
*/
function collect(queues, nums){
var i=0;
for(var j=0; j<queues.length; j++){
while(!queues[j].empty()){
nums[i++] = queues[j].dequeue();
}
}
} //测试程序
//1.定义queues 和 nums
var queues = [];
for (var i = 0; i < 10; ++i) {
queues[i] = new Queue();
}
var nums = [];
for (var i = 0; i < 10; ++i) {
nums[i] = Math.floor(Math.random() * 101);
} console.log("Before radix sort: ");
console.log(nums);
distribute(nums, queues, nums.length, 1); //按照个位数进行第一次排序
collect(queues, nums); //对按照个位数排好序的队列,每个队列挨排出列,组成新的数组
distribute(nums, queues, nums.length, 10); //按照十位数进行第二次排序
collect(queues, nums);
console.log("After radix sort: ");
console.log(nums); </script>

打印出来如下:

3.优先队列:

在一般情况下,从队列中删除的元素,一定是率先入队的元素。
但是也有一些使用队列的应用,在删除元素时不必遵守先进先出的约定。这种应用,需要使用一个叫做优先队列的数据结构来进行模拟。
 
从优先队列中删除元素时, 需要考虑优先权的限制。
比如医院急诊科的候诊室,就是一个采取优先队列的例子。当病人进入候诊室时,分诊护士会评估患者病情的严重程度,然后给一个优先级代码。高优先级的患者先于低优先级的患者就医,同样优先级的患者按照先来先服务的顺序就医。
 
先来定义存储队列元素的对象,然后再构建我们的优先队列系统:
function Patient(name, code) {
  this.name = name;
  this.code = code;
}
变量code 是一个整数,表示患者的优先级或病情严重程度。
 
现在需要重新定义dequeue() 方法,使其删除队列中拥有最高优先级的元素。
我们规定:优先码的值最小的元素优先级最高。
新的dequeue() 方法遍历队列的底层存储数组,从中找出优先码最低的元素,然后使用数组的splice() 方法删除优先级最高的元素。
 
最后,需要定义toString() 方法来显示Patient 对象。
 
 
代码实现如下:
<script type="text/javascript">
function Queue(){
this.dataStore = [];
this.enqueue = enqueue;
this.dequeue = dequeue;
this.front = front;
this.back = back;
this.toString = toString;
this.empty = empty;
this.count = count;
} /**
* 向队尾添加一个元素
*/
function enqueue(element){
this.dataStore.push(element);
} /**
* 使用简单的顺序查找方法寻找优先级最高的元素(优先码越小优先级越高,比如,1 比5 的优先级高)
* 返回包含一个元素的数组——从队列中删除的元素。
*
* 假设第0个位置的优先级最小。
* 找到比这个优先级更小的位置,然后更新位置。
*/
function dequeue(){
var priority = 0;
for(var i=1; i<this.dataStore.length; i++){
if(this.dataStore[i].code < this.dataStore[priority].code){
priority = i;
}
} return this.dataStore.splice(priority, 1);
} /**
* 读取队首的元素:
*/
function front(){
return this.dataStore[0];
} /**
* 读取队尾的元素:
*/
function back(){
return this.dataStore[this.dataStore.length - 1];
} /**
* 显示队列内的所有元素
*/
function toString(){
var retStr = "";
for (var i = 0; i < this.dataStore.length; ++i) {
retStr += this.dataStore[i].name + ", code: "+ this.dataStore[i].code + "\n";
}
return retStr;
} /**
* 判断队列是否为空
*/
function empty(){
if(this.dataStore.length == 0){
return true;
}else{
return false;
}
} /**
* 显示队列中有多少个元素
*/
function count(){
return this.dataStore.length;
} //===================================使用Queue类=============================================
function Patient(name, code) {
this.name = name;
this.code = code;
} //优先队列的实现:
var p = new Patient("Smith",5);
var ed = new Queue();
ed.enqueue(p);
p = new Patient("Jones", 4);
ed.enqueue(p);
p = new Patient("Fehrenbach", 6);
ed.enqueue(p);
p = new Patient("Brown", 1);
ed.enqueue(p);
p = new Patient("Ingram", 1);
ed.enqueue(p);
console.log(ed.toString());
console.log("-------------------------------"); var seen = ed.dequeue();
console.log("Patient being treated: " + seen[0].name);
console.log("Patients waiting to be seen: ");
console.log(ed.toString());
console.log("-------------------------------"); // 下一轮
var seen = ed.dequeue();
console.log("Patient being treated: " + seen[0].name);
console.log("Patients waiting to be seen: ");
console.log(ed.toString());
console.log("-------------------------------"); var seen = ed.dequeue();
console.log("Patient being treated: " + seen[0].name);
console.log("Patients waiting to be seen: ");
console.log(ed.toString()); </script>

打印结果:

数据结构与算法JavaScript描述——使用队列的更多相关文章

  1. 《数据结构与算法JavaScript描述》

    <数据结构与算法JavaScript描述> 基本信息 作者: (美)Michael McMillan 译者: 王群锋 杜欢 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9 ...

  2. 翻阅《数据结构与算法javascript描述》--数组篇

    导读: 这篇文章比较长,介绍了数组常见的操作方法以及一些注意事项,最后还有几道经典的练习题(面试题). 数组的定义: JavaScript 中的数组是一种特殊的对象,用来表示偏移量的索引是该对象的属性 ...

  3. 数据结构与算法javascript描述

    <数据结构与算法javascript描述>--数组篇 导读: 这篇文章比较长,介绍了数组常见的操作方法以及一些注意事项,最后还有几道经典的练习题(面试题). 数组的定义: JavaScri ...

  4. 列表的实现-----数据结构与算法JavaScript描述 第三章

    实现一个列表 script var booklist = new List(); booklist.append('jsbook'); booklist.append('cssbook'); book ...

  5. 《数据结构与算法JavaScript描述》中的一处错误

    最近在看<数据结构与算法JavaScript描述>这本书,看到选择排序这部分时,发现一个比较大的错误. 原书的选择排序算法是这样的: function selectionSort() { ...

  6. 数据结构与算法 Javascript描述

    数据结构与算法系列主要记录<数据结构与算法 Javascript描述>学习心得

  7. 读后感:数据结构与算法JavaScript描述

    本书看完,对常见的数据结构与算法从概念上有了更深入的理解. 书中关于数组.栈和队列.链表.字典.散列.集合.二叉树.图.排序.检索.动态规划.贪心算法都有详细的介绍.算是一本不错的学习书籍. 栈和队列 ...

  8. 数据结构与算法JavaScript描述——队列

    注:澄清一个bug: /** * 删除队首的元素: */ function dequeue(){ return this.dataStore.shift(); } 应该有return:   队列是一种 ...

  9. 队列--数据结构与算法JavaScript描述(5)

    队列 Queue 概念 队列是一种列表,但队列只能在队尾插入元,在队首删除元素. 队列是一种先进先出的数据结构,用于存储按顺序排列的数据,被用在很多地方,比如提交操作系统执行的一系列进程.打印任务池等 ...

随机推荐

  1. WeChat-JSAPI支付

    官方API:打开连接 特别注意----JSAPI只能在微信环境下 测试!2017-04-19 配置:微信公众号中 添加微信支付配置--请认真填写配置并获取下面对应的数据才能正常运行. ======== ...

  2. git重要命令

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  3. volatile关键字解析(二)

    volatile详解接下来,我们详细讲述一下volatile关键字volatile关键字具有两重语义 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这个新值对其他线程来说是 ...

  4. U盘做了一个启动盘来安装Ubuntu,装好后,U盘不能进行格式化了,现在说一下网上找的方法

    参考网址:http://wenwen.sogou.com/z/q289778573.htm 说是这种情况需要对U盘进行低级格式化,具体方法如下: 你可以尝试使用diskpart命令 ① 以管理员身份运 ...

  5. Linux系统下第三方软件安装实例

    在第三方软件安装的时候,首先要有自己的rpm安装包!然后要有可以使用的yum源(前面有关于yum源的介绍) 一.安装wps步骤如下: 1)首先进入安装包所在目录,并查看有没有要安装的软件 2)然后,对 ...

  6. ISO 18000-6c 访问标签--应用程序访问操作ISO 18000-6C标签的方法

    标签访问操作包含三部分: 1.标签选择.某些场景,应用程序只对特定的标签进行操作,Indy Host Library可以指定标签选择条件. 2.执行盘存操作.上报单化后标签EPC区的数据. 3.标签单 ...

  7. (转) MapReduce Design Patterns(chapter 5 (part 1))(九)

    Chapter 5. Join Patterns 把数据保存成一个巨大的数据集不是很常见.例如,用户信息数据频繁更新,所以要保存到关系数据库中.于此同时,web日志以恒定的数据流量增加,直接写到HDF ...

  8. JSCover(查看代码覆盖率)

    1. [文档](http://tntim96.github.io/JSCover/manual/manual.xml)1. [下载](https://sourceforge.net/projects/ ...

  9. caffe 卷积层的运算

    贾清扬寻找快速算法之路:https://github.com/Yangqing/caffe/wiki/Convolution-in-Caffe:-a-memo 卷积运算图文并茂:http://www. ...

  10. typecho去index.php

    RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} ! ...